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) 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/bind.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" 15a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chrome/browser/browser_process.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/browser_shutdown.h" 17a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/ui/app_list/app_list_view_delegate.h" 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/profile_loader.h" 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/profile_store.h" 21a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chrome/common/chrome_constants.h" 22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/common/chrome_switches.h" 23a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "chrome/common/pref_names.h" 24a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 25a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)namespace { 26a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kDiscoverabilityTimeoutMinutes = 60; 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 29a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void SendAppListAppLaunch(int count) { 30a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS( 31a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) "Apps.AppListDailyAppLaunches", count, 1, 1000, 50); 32a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (count > 0) 33a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Apps.AppListHasLaunchedAppToday", 1, 2); 34a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 35a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 36a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void SendAppListLaunch(int count) { 37a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS( 38a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) "Apps.AppListDailyLaunches", count, 1, 1000, 50); 39a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (count > 0) 40a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Apps.AppListHasLaunchedAppListToday", 1, 2); 41a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 42a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 43a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)bool SendDailyEventFrequency( 44a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const char* last_ping_pref, 45a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const char* count_pref, 46a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) void (*send_callback)(int count)) { 47a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) PrefService* local_state = g_browser_process->local_state(); 48a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 49a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::Time now = base::Time::Now(); 50a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::Time last = base::Time::FromInternalValue(local_state->GetInt64( 51a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) last_ping_pref)); 52a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) int days = (now - last).InDays(); 53a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (days > 0) { 54a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) send_callback(local_state->GetInteger(count_pref)); 55a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) local_state->SetInt64( 56a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) last_ping_pref, 57a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) (last + base::TimeDelta::FromDays(days)).ToInternalValue()); 58a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) local_state->SetInteger(count_pref, 0); 59a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return true; 60a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 61a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return false; 62a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 63a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 64a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void RecordDailyEventFrequency( 65a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const char* last_ping_pref, 66a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const char* count_pref, 67a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) void (*send_callback)(int count)) { 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!g_browser_process) 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; // In a unit test. 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 71a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) PrefService* local_state = g_browser_process->local_state(); 72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (!local_state) 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; // In a unit test. 74a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 75a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) int count = local_state->GetInteger(count_pref); 76a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) local_state->SetInteger(count_pref, count + 1); 77a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (SendDailyEventFrequency(last_ping_pref, count_pref, send_callback)) { 78a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) local_state->SetInteger(count_pref, 1); 79a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 80a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 81a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class ProfileStoreImpl : public ProfileStore { 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) explicit ProfileStoreImpl(ProfileManager* profile_manager) 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : profile_manager_(profile_manager), 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_factory_(this) { 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 88ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void AddProfileObserver(ProfileInfoCacheObserver* observer) OVERRIDE { 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) profile_manager_->GetProfileInfoCache().AddObserver(observer); 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void LoadProfileAsync( 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const base::FilePath& path, 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Callback<void(Profile*)> callback) OVERRIDE { 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) profile_manager_->CreateProfileAsync( 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) path, 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&ProfileStoreImpl::OnProfileCreated, 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) weak_factory_.GetWeakPtr(), 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) callback), 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::string16(), 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::string16(), 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string()); 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) void OnProfileCreated(base::Callback<void(Profile*)> callback, 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Profile* profile, 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Profile::CreateStatus status) { 1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) switch (status) { 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case Profile::CREATE_STATUS_CREATED: 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case Profile::CREATE_STATUS_INITIALIZED: 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) callback.Run(profile); 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case Profile::CREATE_STATUS_LOCAL_FAIL: 1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case Profile::CREATE_STATUS_REMOTE_FAIL: 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case Profile::CREATE_STATUS_CANCELED: 1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) case Profile::MAX_CREATE_STATUS: 1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) NOTREACHED(); 1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) break; 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual Profile* GetProfileByPath(const base::FilePath& path) OVERRIDE { 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return profile_manager_->GetProfileByPath(path); 1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual base::FilePath GetUserDataDir() OVERRIDE { 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return profile_manager_->user_data_dir(); 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual bool IsProfileSupervised( 134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const base::FilePath& profile_path) OVERRIDE { 1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ProfileInfoCache& profile_info = 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) g_browser_process->profile_manager()->GetProfileInfoCache(); 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t profile_index = profile_info.GetIndexOfProfileWithPath(profile_path); 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return profile_index != std::string::npos && 139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) profile_info.ProfileIsSupervisedAtIndex(profile_index); 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ProfileManager* profile_manager_; 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::WeakPtrFactory<ProfileStoreImpl> weak_factory_; 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 146ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void RecordAppListDiscoverability(PrefService* local_state, 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool is_startup_check) { 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Since this task may be delayed, ensure it does not interfere with shutdown 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // when they unluckily coincide. 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (browser_shutdown::IsTryingToQuit()) 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 enable_time_value = local_state->GetInt64(prefs::kAppListEnableTime); 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (enable_time_value == 0) 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; // Already recorded or never enabled. 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time app_list_enable_time = 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time::FromInternalValue(enable_time_value); 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (is_startup_check) { 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // When checking at startup, only clear and record the "timeout" case, 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // otherwise wait for a timeout. 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta time_remaining = 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) app_list_enable_time + 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta::FromMinutes(kDiscoverabilityTimeoutMinutes) - 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time::Now(); 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (time_remaining > base::TimeDelta()) { 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&RecordAppListDiscoverability, 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(local_state), 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) false), 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) time_remaining); 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) local_state->SetInt64(prefs::kAppListEnableTime, 0); 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppListService::AppListEnableSource enable_source = 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<AppListService::AppListEnableSource>( 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) local_state->GetInteger(prefs::kAppListEnableMethod)); 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (enable_source == AppListService::ENABLE_FOR_APP_INSTALL) { 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta time_taken = base::Time::Now() - app_list_enable_time; 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This means the user "discovered" the app launcher naturally, after it was 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // enabled on the first app install. Record how long it took to discover. 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Note that the last bucket is essentially "not discovered": subtract 1 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // minute to account for clock inaccuracy. 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES( 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "Apps.AppListTimeToDiscover", 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) time_taken, 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta::FromSeconds(1), 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta::FromMinutes(kDiscoverabilityTimeoutMinutes - 1), 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10 /* bucket_count */); 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Apps.AppListHowEnabled", 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) enable_source, 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppListService::ENABLE_NUM_ENABLE_SOURCES); 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 201a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} // namespace 202a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 203a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void AppListServiceImpl::RecordAppListLaunch() { 204a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) RecordDailyEventFrequency(prefs::kLastAppListLaunchPing, 205a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) prefs::kAppListLaunchCount, 206a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) &SendAppListLaunch); 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RecordAppListDiscoverability(local_state_, false); 208a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 209a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 210a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// static 211a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void AppListServiceImpl::RecordAppListAppLaunch() { 212a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) RecordDailyEventFrequency(prefs::kLastAppListAppLaunchPing, 213a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) prefs::kAppListAppLaunchCount, 214a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) &SendAppListAppLaunch); 215a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 216a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 217a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// static 218a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void AppListServiceImpl::SendAppListStats() { 219a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (!g_browser_process || g_browser_process->IsShuttingDown()) 220a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return; 221a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 222a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) SendDailyEventFrequency(prefs::kLastAppListLaunchPing, 223a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) prefs::kAppListLaunchCount, 224a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) &SendAppListLaunch); 225a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) SendDailyEventFrequency(prefs::kLastAppListAppLaunchPing, 226a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) prefs::kAppListAppLaunchCount, 227a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) &SendAppListAppLaunch); 228a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 229a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 230a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)AppListServiceImpl::AppListServiceImpl() 2310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch : profile_store_( 2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch new ProfileStoreImpl(g_browser_process->profile_manager())), 2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) command_line_(*CommandLine::ForCurrentProcess()), 2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) local_state_(g_browser_process->local_state()), 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci profile_loader_(new ProfileLoader(profile_store_.get())), 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_(this) { 2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) profile_store_->AddProfileObserver(this); 2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2400529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochAppListServiceImpl::AppListServiceImpl(const CommandLine& command_line, 2410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch PrefService* local_state, 2420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<ProfileStore> profile_store) 2431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) : profile_store_(profile_store.Pass()), 2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) command_line_(command_line), 2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) local_state_(local_state), 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci profile_loader_(new ProfileLoader(profile_store_.get())), 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_(this) { 2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) profile_store_->AddProfileObserver(this); 249a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 250a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 251a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)AppListServiceImpl::~AppListServiceImpl() {} 252a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciAppListViewDelegate* AppListServiceImpl::GetViewDelegate(Profile* profile) { 2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!view_delegate_) 2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci view_delegate_.reset(new AppListViewDelegate(GetControllerDelegate())); 2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci view_delegate_->SetProfile(profile); 2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return view_delegate_.get(); 2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AppListServiceImpl::SetAppListNextPaintCallback(void (*callback)()) {} 2613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 262ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid AppListServiceImpl::HandleFirstRun() {} 263ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 264a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void AppListServiceImpl::Init(Profile* initial_profile) {} 265a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)base::FilePath AppListServiceImpl::GetProfilePath( 267a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const base::FilePath& user_data_dir) { 268a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) std::string app_list_profile; 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (local_state_->HasPrefPath(prefs::kAppListProfile)) 2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) app_list_profile = local_state_->GetString(prefs::kAppListProfile); 271a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 272a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // If the user has no profile preference for the app launcher, default to the 273a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // last browser profile used. 274a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (app_list_profile.empty() && 2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) local_state_->HasPrefPath(prefs::kProfileLastUsed)) { 2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) app_list_profile = local_state_->GetString(prefs::kProfileLastUsed); 277ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 278ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 279ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // If there is no last used profile recorded, use the initial profile. 280ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (app_list_profile.empty()) 281ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch app_list_profile = chrome::kInitialProfile; 282a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 283ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return user_data_dir.AppendASCII(app_list_profile); 284ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 285a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 286ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid AppListServiceImpl::SetProfilePath(const base::FilePath& profile_path) { 2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) local_state_->SetString( 288ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch prefs::kAppListProfile, 289ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch profile_path.BaseName().MaybeAsASCII()); 290a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 291a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 292ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid AppListServiceImpl::CreateShortcut() {} 293a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 294a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void AppListServiceImpl::OnProfileWillBeRemoved( 295a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const base::FilePath& profile_path) { 2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // We need to watch for profile removal to keep kAppListProfile updated, for 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // the case that the deleted profile is being used by the app list. 2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string app_list_last_profile = local_state_->GetString( 299a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) prefs::kAppListProfile); 3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (profile_path.BaseName().MaybeAsASCII() != app_list_last_profile) 3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Switch the app list over to a valid profile. 3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Before ProfileInfoCache::DeleteProfileFromCache() calls this function, 3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // ProfileManager::ScheduleProfileForDeletion() will have checked to see if 3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // the deleted profile was also "last used", and updated that setting with 3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // something valid. 3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci local_state_->SetString(prefs::kAppListProfile, 3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci local_state_->GetString(prefs::kProfileLastUsed)); 3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If the app list was never shown, there won't be a |view_delegate_| yet. 3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!view_delegate_) 3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The Chrome AppListViewDelegate now needs its profile cleared, because: 3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 1. it has many references to the profile and can't be profile-keyed, and 3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 2. the last used profile might not be loaded yet. 3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // - this loading is sometimes done by the ProfileManager asynchronously, 3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // so the app list can't just switch to that. 3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Only Mac supports showing the app list with a NULL profile, so tear down 3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // the view. 3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DestroyAppList(); 3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci view_delegate_->SetProfile(NULL); 324a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 325a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 326ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid AppListServiceImpl::Show() { 3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) profile_loader_->LoadProfileInvalidatingOtherLoads( 3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GetProfilePath(profile_store_->GetUserDataDir()), 329ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Bind(&AppListServiceImpl::ShowForProfile, 330ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch weak_factory_.GetWeakPtr())); 331a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 332a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppListServiceImpl::AutoShowForProfile(Profile* requested_profile) { 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (local_state_->GetInt64(prefs::kAppListEnableTime) != 0) { 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // User has not yet discovered the app launcher. Update the enable method to 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // indicate this. It will then be recorded in UMA. 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) local_state_->SetInteger(prefs::kAppListEnableMethod, 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ENABLE_SHOWN_UNDISCOVERED); 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ShowForProfile(requested_profile); 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppListServiceImpl::EnableAppList(Profile* initial_profile, 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AppListEnableSource enable_source) { 345ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch SetProfilePath(initial_profile->GetPath()); 346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Always allow the webstore "enable" button to re-run the install flow. 347a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (enable_source != AppListService::ENABLE_VIA_WEBSTORE_LINK && 348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) local_state_->GetBoolean(prefs::kAppLauncherHasBeenEnabled)) { 349ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return; 350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 351ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 3524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) local_state_->SetBoolean(prefs::kAppLauncherHasBeenEnabled, true); 353ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch CreateShortcut(); 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // UMA for launcher discoverability. 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) local_state_->SetInt64(prefs::kAppListEnableTime, 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time::Now().ToInternalValue()); 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) local_state_->SetInteger(prefs::kAppListEnableMethod, enable_source); 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (base::MessageLoop::current()) { 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Ensure a value is recorded if the user "never" shows the app list. Note 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // there is no message loop in unit tests. 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&RecordAppListDiscoverability, 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(local_state_), 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) false), 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta::FromMinutes(kDiscoverabilityTimeoutMinutes)); 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 369a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 370a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 371a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void AppListServiceImpl::InvalidatePendingProfileLoads() { 3724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) profile_loader_->InvalidatePendingProfileLoads(); 373a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 374a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppListServiceImpl::PerformStartupChecks(Profile* initial_profile) { 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Except in rare, once-off cases, this just checks that a pref is "0" and 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // returns. 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RecordAppListDiscoverability(local_state_, true); 379ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 3808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (command_line_.HasSwitch(switches::kResetAppListInstallState)) 3814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) local_state_->SetBoolean(prefs::kAppLauncherHasBeenEnabled, false); 38268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (command_line_.HasSwitch(switches::kEnableAppList)) 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EnableAppList(initial_profile, ENABLE_VIA_COMMAND_LINE); 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!base::MessageLoop::current()) 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; // In a unit test. 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 38968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Send app list usage stats after a delay. 39068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const int kSendUsageStatsDelay = 5; 39168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 39268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) FROM_HERE, 39368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&AppListServiceImpl::SendAppListStats), 39468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::TimeDelta::FromSeconds(kSendUsageStatsDelay)); 395a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 396