1// Copyright 2014 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 "components/signin/core/common/profile_management_switches.h"
6
7#include "base/command_line.h"
8#include "base/metrics/field_trial.h"
9#include "build/build_config.h"
10#include "components/signin/core/common/signin_switches.h"
11
12namespace {
13
14const char kNewProfileManagementFieldTrialName[] = "NewProfileManagement";
15
16// Different state of new profile management/identity consistency.  The code
17// below assumes the order of the values in this enum.  That is, new profile
18// management is included in consistent identity.
19enum State {
20  STATE_OLD_AVATAR_MENU,
21  STATE_NEW_AVATAR_MENU,
22  STATE_NEW_PROFILE_MANAGEMENT,
23  STATE_ACCOUNT_CONSISTENCY,
24};
25
26State GetProcessState() {
27  // Disables the new avatar menu if the web-based signin is turned on, because
28  // the new avatar menu always uses the inline signin, which may break some
29  // SAML users.
30  if (switches::IsEnableWebBasedSignin())
31    return STATE_OLD_AVATAR_MENU;
32
33  // Find the state of both command line args.
34  bool is_new_avatar_menu =
35      CommandLine::ForCurrentProcess()->HasSwitch(
36          switches::kEnableNewAvatarMenu);
37  bool is_new_profile_management =
38      CommandLine::ForCurrentProcess()->HasSwitch(
39          switches::kEnableNewProfileManagement);
40  bool is_consistent_identity =
41      CommandLine::ForCurrentProcess()->HasSwitch(
42          switches::kEnableAccountConsistency);
43  bool not_new_avatar_menu =
44      CommandLine::ForCurrentProcess()->HasSwitch(
45          switches::kDisableNewAvatarMenu);
46  bool not_new_profile_management =
47      CommandLine::ForCurrentProcess()->HasSwitch(
48          switches::kDisableNewProfileManagement);
49  bool not_consistent_identity =
50      CommandLine::ForCurrentProcess()->HasSwitch(
51          switches::kDisableAccountConsistency);
52  int count_args = (is_new_avatar_menu ? 1 : 0) +
53      (is_new_profile_management ? 1 : 0) +
54      (is_consistent_identity ? 1 : 0) +
55      (not_new_avatar_menu ? 1 : 0) +
56      (not_new_profile_management ? 1 : 0) +
57      (not_consistent_identity ? 1 : 0);
58  bool invalid_commandline = count_args > 1;
59
60  // At most only one of the command line args should be specified, otherwise
61  // the finch group assignment is undefined.  If this is the case, disable
62  // the field trial so that data is not collected in the wrong group.
63  std::string trial_type;
64  if (invalid_commandline) {
65    base::FieldTrial* field_trial =
66        base::FieldTrialList::Find(kNewProfileManagementFieldTrialName);
67    if (field_trial)
68      field_trial->Disable();
69
70    trial_type.clear();
71  } else {
72    // Since the experiment is not being disabled, get the full name of the
73    // field trial which will initialize the underlying mechanism.
74    trial_type =
75        base::FieldTrialList::FindFullName(kNewProfileManagementFieldTrialName);
76  }
77
78  // Forcing the old avatar menu takes precedent over other args.
79  // Enable command line args take precedent over disable command line args.
80  // Consistent identity args take precedent over new profile management args.
81  if (not_new_avatar_menu) {
82    return STATE_OLD_AVATAR_MENU;
83  } else if (is_consistent_identity) {
84    return STATE_ACCOUNT_CONSISTENCY;
85  } else if (is_new_profile_management) {
86    return STATE_NEW_PROFILE_MANAGEMENT;
87  } else if (is_new_avatar_menu) {
88    return STATE_NEW_AVATAR_MENU;
89  } else if (not_new_profile_management) {
90    return STATE_OLD_AVATAR_MENU;
91  } else if (not_consistent_identity) {
92    return STATE_OLD_AVATAR_MENU;
93  }
94
95  // Set the default state
96#if defined(OS_ANDROID)
97  State state = STATE_ACCOUNT_CONSISTENCY;
98#else
99  State state = STATE_OLD_AVATAR_MENU;
100#endif
101
102  if (!trial_type.empty()) {
103    if (trial_type == "Enabled") {
104      state = STATE_NEW_PROFILE_MANAGEMENT;
105    } else if (trial_type == "AccountConsistency") {
106      state = STATE_ACCOUNT_CONSISTENCY;
107    } else if (trial_type == "NewAvatarMenu") {
108      state = STATE_NEW_AVATAR_MENU;
109    } else {
110      state = STATE_OLD_AVATAR_MENU;
111    }
112  }
113
114  return state;
115}
116
117bool CheckFlag(std::string command_switch, State min_state) {
118  // Individiual flag settings take precedence.
119  if (CommandLine::ForCurrentProcess()->HasSwitch(command_switch))
120    return true;
121
122  return GetProcessState() >= min_state;
123}
124
125}  // namespace
126
127namespace switches {
128
129bool IsEnableAccountConsistency() {
130  return GetProcessState() >= STATE_ACCOUNT_CONSISTENCY;
131}
132
133bool IsEnableWebBasedSignin() {
134  return CommandLine::ForCurrentProcess()->HasSwitch(
135      switches::kEnableWebBasedSignin);
136}
137
138bool IsExtensionsMultiAccount() {
139  return CheckFlag(switches::kExtensionsMultiAccount,
140                   STATE_NEW_PROFILE_MANAGEMENT);
141}
142
143bool IsFastUserSwitching() {
144  return CommandLine::ForCurrentProcess()->HasSwitch(
145      switches::kFastUserSwitching);
146}
147
148bool IsGoogleProfileInfo() {
149  return CheckFlag(switches::kGoogleProfileInfo, STATE_NEW_AVATAR_MENU);
150}
151
152bool IsNewAvatarMenu() {
153  // NewAvatarMenu is only available on desktop.
154#if defined(OS_ANDROID) || defined(OS_IOS) || defined(OS_CHROMEOS)
155  return false;
156#else
157  return GetProcessState() >= STATE_NEW_AVATAR_MENU;
158#endif
159}
160
161bool IsNewProfileManagement() {
162  return GetProcessState() >= STATE_NEW_PROFILE_MANAGEMENT;
163}
164
165bool IsNewProfileManagementPreviewEnabled() {
166  // No promotion to Enable Account Consistency.
167  return false;
168}
169
170void EnableNewAvatarMenuForTesting(base::CommandLine* command_line) {
171  command_line->AppendSwitch(switches::kEnableNewAvatarMenu);
172  DCHECK(!command_line->HasSwitch(switches::kDisableNewAvatarMenu));
173}
174
175void DisableNewAvatarMenuForTesting(base::CommandLine* command_line) {
176  command_line->AppendSwitch(switches::kDisableNewAvatarMenu);
177  DCHECK(!command_line->HasSwitch(switches::kEnableNewAvatarMenu));
178}
179
180void EnableNewProfileManagementForTesting(base::CommandLine* command_line) {
181  command_line->AppendSwitch(switches::kEnableNewProfileManagement);
182  DCHECK(!command_line->HasSwitch(switches::kDisableNewProfileManagement));
183}
184
185void EnableAccountConsistencyForTesting(base::CommandLine* command_line) {
186  command_line->AppendSwitch(switches::kEnableAccountConsistency);
187  DCHECK(!command_line->HasSwitch(switches::kDisableAccountConsistency));
188}
189
190}  // namespace switches
191