blob: 9c836eddc13cbf38b04820f336aba0fbb1f56fa6 [file] [log] [blame]
[email protected]5ee08bf2013-11-30 05:25:301// 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
[email protected]980d5f9e2013-12-17 17:47:085#include "base/command_line.h"
avi8a07d53892015-12-24 22:13:536#include "base/macros.h"
asvitkineb56637512016-09-01 19:41:407#include "base/metrics/histogram_macros.h"
[email protected]4d390782014-08-15 09:22:588#include "chrome/browser/browser_process.h"
[email protected]980d5f9e2013-12-17 17:47:089#include "chrome/browser/chrome_notification_types.h"
updowndota07ecbf22017-06-28 05:34:0610#include "chrome/browser/chromeos/arc/arc_util.h"
11#include "chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service.h"
[email protected]5ee08bf2013-11-30 05:25:3012#include "chrome/browser/chromeos/first_run/first_run_controller.h"
updowndotaec4980672017-06-08 02:11:1413#include "chrome/browser/chromeos/login/ui/login_display_host.h"
14#include "chrome/browser/chromeos/login/wizard_controller.h"
[email protected]052e3ac2014-06-30 14:22:4715#include "chrome/browser/chromeos/profiles/profile_helper.h"
[email protected]5ee08bf2013-11-30 05:25:3016#include "chrome/browser/extensions/extension_service.h"
Denis Kuznetsovd124ec82017-08-11 23:43:4917#include "chrome/browser/policy/profile_policy_connector.h"
18#include "chrome/browser/policy/profile_policy_connector_factory.h"
sdefresneed27d86b2015-09-14 11:02:3819#include "chrome/browser/prefs/pref_service_syncable_util.h"
Hidehiko Abebac30e62017-07-18 03:52:5820#include "chrome/browser/profiles/profile.h"
Yue Li3a608342017-08-09 06:03:4621#include "chrome/browser/signin/signin_manager_factory.h"
cylee49e02a92014-12-01 19:03:3922#include "chrome/browser/ui/extensions/app_launch_params.h"
[email protected]5ee08bf2013-11-30 05:25:3023#include "chrome/browser/ui/extensions/application_launch.h"
[email protected]980d5f9e2013-12-17 17:47:0824#include "chrome/common/chrome_switches.h"
lfg3fba1a62014-11-04 22:26:2525#include "chrome/common/extensions/extension_constants.h"
[email protected]980d5f9e2013-12-17 17:47:0826#include "chrome/common/pref_names.h"
27#include "chromeos/chromeos_switches.h"
updowndota07ecbf22017-06-28 05:34:0628#include "components/arc/arc_service_manager.h"
[email protected]f0c8c4992014-05-15 17:37:2629#include "components/pref_registry/pref_registry_syncable.h"
brettwb1fc1b82016-02-02 00:19:0830#include "components/prefs/pref_service.h"
Yue Li3a608342017-08-09 06:03:4631#include "components/signin/core/browser/account_info.h"
32#include "components/signin/core/browser/account_tracker_service.h"
33#include "components/signin/core/browser/signin_manager.h"
maxbogueea16ff412016-10-28 16:35:2934#include "components/sync_preferences/pref_service_syncable.h"
[email protected]4d390782014-08-15 09:22:5835#include "components/user_manager/user_manager.h"
[email protected]980d5f9e2013-12-17 17:47:0836#include "content/public/browser/notification_observer.h"
37#include "content/public/browser/notification_registrar.h"
38#include "content/public/browser/notification_service.h"
brettw90e92602015-10-10 00:12:4039#include "content/public/common/content_switches.h"
[email protected]59b0e602014-01-30 00:41:2440#include "extensions/browser/extension_system.h"
[email protected]5ee08bf2013-11-30 05:25:3041#include "extensions/common/constants.h"
updowndota07ecbf22017-06-28 05:34:0642#include "ui/gfx/geometry/rect.h"
[email protected]5ee08bf2013-11-30 05:25:3043
44namespace chromeos {
[email protected]980d5f9e2013-12-17 17:47:0845namespace first_run {
[email protected]5ee08bf2013-11-30 05:25:3046
[email protected]980d5f9e2013-12-17 17:47:0847namespace {
48
49void LaunchDialogForProfile(Profile* profile) {
[email protected]5ee08bf2013-11-30 05:25:3050 ExtensionService* service =
51 extensions::ExtensionSystem::Get(profile)->extension_service();
52 if (!service)
53 return;
54
55 const extensions::Extension* extension =
56 service->GetExtensionById(extension_misc::kFirstRunDialogId, false);
57 if (!extension)
58 return;
59
nick3b04f322016-08-31 19:29:1960 OpenApplication(AppLaunchParams(
61 profile, extension, extensions::LAUNCH_CONTAINER_WINDOW,
62 WindowOpenDisposition::NEW_WINDOW, extensions::SOURCE_CHROME_INTERNAL));
[email protected]980d5f9e2013-12-17 17:47:0863 profile->GetPrefs()->SetBoolean(prefs::kFirstRunTutorialShown, true);
[email protected]5ee08bf2013-11-30 05:25:3064}
65
muyuanlic20d3c02017-05-19 00:39:3266void TryLaunchFirstRunDialog(Profile* profile) {
67 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
68
69 if (command_line->HasSwitch(switches::kOobeSkipPostLogin))
70 return;
71
72 if (command_line->HasSwitch(switches::kForceFirstRunUI)) {
73 LaunchDialogForProfile(profile);
74 return;
75 }
76
Denis Kuznetsovd124ec82017-08-11 23:43:4977 if (policy::ProfilePolicyConnectorFactory::GetForBrowserContext(profile)
78 ->IsManaged())
79 return;
80
muyuanlic20d3c02017-05-19 00:39:3281 if (command_line->HasSwitch(::switches::kTestType))
82 return;
83
84 if (!user_manager::UserManager::Get()->IsCurrentUserNew())
85 return;
86
87 if (profile->GetPrefs()->GetBoolean(prefs::kFirstRunTutorialShown))
88 return;
89
90 bool is_pref_synced =
91 PrefServiceSyncableFromProfile(profile)->IsPrioritySyncing();
92 bool is_user_ephemeral = user_manager::UserManager::Get()
93 ->IsCurrentUserNonCryptohomeDataEphemeral();
94 if (!is_pref_synced && is_user_ephemeral)
95 return;
96
97 LaunchDialogForProfile(profile);
98}
99
[email protected]980d5f9e2013-12-17 17:47:08100// Object of this class waits for session start. Then it launches or not
101// launches first-run dialog depending on user prefs and flags. Than object
102// deletes itself.
103class DialogLauncher : public content::NotificationObserver {
104 public:
105 explicit DialogLauncher(Profile* profile)
106 : profile_(profile) {
107 DCHECK(profile);
108 registrar_.Add(this,
109 chrome::NOTIFICATION_SESSION_STARTED,
110 content::NotificationService::AllSources());
111 }
112
dchengc97a0282015-01-15 23:04:24113 ~DialogLauncher() override {}
[email protected]980d5f9e2013-12-17 17:47:08114
dchengc97a0282015-01-15 23:04:24115 void Observe(int type,
116 const content::NotificationSource& source,
117 const content::NotificationDetails& details) override {
[email protected]980d5f9e2013-12-17 17:47:08118 DCHECK(type == chrome::NOTIFICATION_SESSION_STARTED);
[email protected]2fda9972014-07-23 14:51:59119 DCHECK(content::Details<const user_manager::User>(details).ptr() ==
[email protected]052e3ac2014-06-30 14:22:47120 ProfileHelper::Get()->GetUserByProfile(profile_));
updowndotaec4980672017-06-08 02:11:14121
Yue Li3a608342017-08-09 06:03:46122 // Whether the account is supported for voice interaction.
123 bool account_supported = false;
124 SigninManagerBase* signin_manager =
125 SigninManagerFactory::GetForProfile(profile_);
126 if (signin_manager) {
127 std::string hosted_domain =
128 signin_manager->GetAuthenticatedAccountInfo().hosted_domain;
129 if (hosted_domain == AccountTrackerService::kNoHostedDomainFound ||
130 hosted_domain == "google.com")
131 account_supported = true;
132 }
133
updowndota07ecbf22017-06-28 05:34:06134 // If voice interaction value prop needs to be shown, the tutorial will be
updowndotaec4980672017-06-08 02:11:14135 // shown after the voice interaction OOBE flow.
Yue Li3a608342017-08-09 06:03:46136 if (account_supported && arc::IsArcPlayStoreEnabledForProfile(profile_) &&
updowndota07ecbf22017-06-28 05:34:06137 !profile_->GetPrefs()->GetBoolean(
138 prefs::kArcVoiceInteractionValuePropAccepted)) {
139 auto* service =
Hidehiko Abebac30e62017-07-18 03:52:58140 arc::ArcVoiceInteractionFrameworkService::GetForBrowserContext(
141 profile_);
updowndota07ecbf22017-06-28 05:34:06142 if (service)
143 service->StartSessionFromUserInteraction(gfx::Rect());
144 } else {
updowndotaec4980672017-06-08 02:11:14145 TryLaunchFirstRunDialog(profile_);
updowndota07ecbf22017-06-28 05:34:06146 }
147
[email protected]980d5f9e2013-12-17 17:47:08148 delete this;
149 }
150
151 private:
152 Profile* profile_;
153 content::NotificationRegistrar registrar_;
154
155 DISALLOW_COPY_AND_ASSIGN(DialogLauncher);
156};
157
158} // namespace
159
160void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
Sarah Hu00eaa5a2017-08-14 17:16:13161 // This preference used to be syncable, change it to non-syncable so new
162 // users will always see the welcome app on a new device.
163 // See crbug.com/752361
164 registry->RegisterBooleanPref(prefs::kFirstRunTutorialShown, false);
[email protected]980d5f9e2013-12-17 17:47:08165}
166
167void MaybeLaunchDialogAfterSessionStart() {
[email protected]64268342014-08-12 17:18:22168 new DialogLauncher(ProfileHelper::Get()->GetProfileByUserUnsafe(
[email protected]4d390782014-08-15 09:22:58169 user_manager::UserManager::Get()->GetActiveUser()));
[email protected]980d5f9e2013-12-17 17:47:08170}
171
muyuanlic20d3c02017-05-19 00:39:32172void MaybeLaunchDialogImmediately() {
173 TryLaunchFirstRunDialog(ProfileHelper::Get()->GetProfileByUser(
174 user_manager::UserManager::Get()->GetActiveUser()));
175}
176
[email protected]980d5f9e2013-12-17 17:47:08177void LaunchTutorial() {
[email protected]1876f392014-01-16 16:13:57178 UMA_HISTOGRAM_BOOLEAN("CrosFirstRun.TutorialLaunched", true);
[email protected]5ee08bf2013-11-30 05:25:30179 FirstRunController::Start();
180}
181
[email protected]980d5f9e2013-12-17 17:47:08182} // namespace first_run
[email protected]5ee08bf2013-11-30 05:25:30183} // namespace chromeos