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 "base/command_line.h"
6#include "base/metrics/histogram.h"
7#include "base/prefs/pref_service.h"
8#include "chrome/browser/browser_process.h"
9#include "chrome/browser/chrome_notification_types.h"
10#include "chrome/browser/chromeos/first_run/first_run_controller.h"
11#include "chrome/browser/chromeos/profiles/profile_helper.h"
12#include "chrome/browser/extensions/extension_service.h"
13#include "chrome/browser/profiles/profile_manager.h"
14#include "chrome/browser/ui/extensions/application_launch.h"
15#include "chrome/common/chrome_switches.h"
16#include "chrome/common/pref_names.h"
17#include "chromeos/chromeos_switches.h"
18#include "components/pref_registry/pref_registry_syncable.h"
19#include "components/user_manager/user_manager.h"
20#include "content/public/browser/notification_observer.h"
21#include "content/public/browser/notification_registrar.h"
22#include "content/public/browser/notification_service.h"
23#include "extensions/browser/extension_system.h"
24#include "extensions/common/constants.h"
25
26namespace chromeos {
27namespace first_run {
28
29namespace {
30
31void LaunchDialogForProfile(Profile* profile) {
32  ExtensionService* service =
33      extensions::ExtensionSystem::Get(profile)->extension_service();
34  if (!service)
35    return;
36
37  const extensions::Extension* extension =
38      service->GetExtensionById(extension_misc::kFirstRunDialogId, false);
39  if (!extension)
40    return;
41
42  OpenApplication(AppLaunchParams(
43      profile, extension, extensions::LAUNCH_CONTAINER_WINDOW, NEW_WINDOW));
44  profile->GetPrefs()->SetBoolean(prefs::kFirstRunTutorialShown, true);
45}
46
47// Object of this class waits for session start. Then it launches or not
48// launches first-run dialog depending on user prefs and flags. Than object
49// deletes itself.
50class DialogLauncher : public content::NotificationObserver {
51 public:
52  explicit DialogLauncher(Profile* profile)
53      : profile_(profile) {
54    DCHECK(profile);
55    registrar_.Add(this,
56                   chrome::NOTIFICATION_SESSION_STARTED,
57                   content::NotificationService::AllSources());
58  }
59
60  virtual ~DialogLauncher() {}
61
62  virtual void Observe(int type,
63                       const content::NotificationSource& source,
64                       const content::NotificationDetails& details) OVERRIDE {
65    DCHECK(type == chrome::NOTIFICATION_SESSION_STARTED);
66    DCHECK(content::Details<const user_manager::User>(details).ptr() ==
67           ProfileHelper::Get()->GetUserByProfile(profile_));
68    CommandLine* command_line = CommandLine::ForCurrentProcess();
69    bool launched_in_test = command_line->HasSwitch(::switches::kTestType);
70    bool launched_in_telemetry =
71        command_line->HasSwitch(switches::kOobeSkipPostLogin);
72    bool is_user_new = user_manager::UserManager::Get()->IsCurrentUserNew();
73    bool first_run_forced = command_line->HasSwitch(switches::kForceFirstRunUI);
74    bool first_run_seen =
75        profile_->GetPrefs()->GetBoolean(prefs::kFirstRunTutorialShown);
76    if (!launched_in_telemetry &&
77        ((is_user_new && !first_run_seen && !launched_in_test) ||
78         first_run_forced)) {
79      LaunchDialogForProfile(profile_);
80    }
81    delete this;
82  }
83
84 private:
85  Profile* profile_;
86  content::NotificationRegistrar registrar_;
87
88  DISALLOW_COPY_AND_ASSIGN(DialogLauncher);
89};
90
91}  // namespace
92
93void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
94  registry->RegisterBooleanPref(
95      prefs::kFirstRunTutorialShown,
96      false,
97      user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
98}
99
100void MaybeLaunchDialogAfterSessionStart() {
101  new DialogLauncher(ProfileHelper::Get()->GetProfileByUserUnsafe(
102      user_manager::UserManager::Get()->GetActiveUser()));
103}
104
105void LaunchTutorial() {
106  UMA_HISTOGRAM_BOOLEAN("CrosFirstRun.TutorialLaunched", true);
107  FirstRunController::Start();
108}
109
110}  // namespace first_run
111}  // namespace chromeos
112