Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / browser / ui / webui / options / supervised_user_import_handler.cc
blobf3cbf1165032408b69d3b9b897e455362b31e047
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.
5 #include "chrome/browser/ui/webui/options/supervised_user_import_handler.h"
7 #include <set>
9 #include "base/bind.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/values.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
15 #include "chrome/browser/profiles/profile_info_cache.h"
16 #include "chrome/browser/profiles/profile_manager.h"
17 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
18 #include "chrome/browser/signin/signin_manager_factory.h"
19 #include "chrome/browser/supervised_user/supervised_user_constants.h"
20 #include "chrome/browser/supervised_user/supervised_user_shared_settings_service.h"
21 #include "chrome/browser/supervised_user/supervised_user_shared_settings_service_factory.h"
22 #include "chrome/browser/supervised_user/supervised_user_sync_service.h"
23 #include "chrome/browser/supervised_user/supervised_user_sync_service_factory.h"
24 #include "chrome/common/pref_names.h"
25 #include "chrome/common/url_constants.h"
26 #include "chrome/grit/generated_resources.h"
27 #include "components/signin/core/browser/profile_oauth2_token_service.h"
28 #include "components/signin/core/browser/signin_error_controller.h"
29 #include "components/signin/core/browser/signin_manager.h"
30 #include "content/public/browser/web_ui.h"
31 #include "grit/theme_resources.h"
33 namespace {
35 scoped_ptr<base::ListValue> GetAvatarIcons() {
36 scoped_ptr<base::ListValue> avatar_icons(new base::ListValue);
37 for (size_t i = 0; i < profiles::GetDefaultAvatarIconCount(); ++i) {
38 std::string avatar_url = profiles::GetDefaultAvatarIconUrl(i);
39 avatar_icons->Append(new base::StringValue(avatar_url));
42 return avatar_icons.Pass();
45 } // namespace
47 namespace options {
49 SupervisedUserImportHandler::SupervisedUserImportHandler()
50 : observer_(this),
51 weak_ptr_factory_(this) {}
53 SupervisedUserImportHandler::~SupervisedUserImportHandler() {
54 Profile* profile = Profile::FromWebUI(web_ui());
55 if (!profile->IsSupervised()) {
56 SupervisedUserSyncService* service =
57 SupervisedUserSyncServiceFactory::GetForProfile(profile);
58 if (service)
59 service->RemoveObserver(this);
60 subscription_.reset();
64 void SupervisedUserImportHandler::GetLocalizedValues(
65 base::DictionaryValue* localized_strings) {
66 DCHECK(localized_strings);
68 static OptionsStringResource resources[] = {
69 { "supervisedUserImportTitle",
70 IDS_IMPORT_EXISTING_SUPERVISED_USER_TITLE },
71 { "supervisedUserImportText", IDS_IMPORT_EXISTING_SUPERVISED_USER_TEXT },
72 { "createNewUserLink", IDS_CREATE_NEW_USER_LINK },
73 { "supervisedUserImportOk", IDS_IMPORT_EXISTING_SUPERVISED_USER_OK },
74 { "supervisedUserImportSigninError",
75 IDS_SUPERVISED_USER_IMPORT_SIGN_IN_ERROR },
76 { "supervisedUserAlreadyOnThisDevice",
77 IDS_SUPERVISED_USER_ALREADY_ON_THIS_DEVICE },
78 { "noExistingSupervisedUsers", IDS_SUPERVISED_USER_NO_EXISTING_ERROR },
79 { "supervisedUserSelectAvatarTitle",
80 IDS_SUPERVISED_USER_SELECT_AVATAR_TITLE },
81 { "supervisedUserSelectAvatarText",
82 IDS_SUPERVISED_USER_SELECT_AVATAR_TEXT },
83 { "supervisedUserSelectAvatarOk", IDS_SUPERVISED_USER_SELECT_AVATAR_OK },
86 RegisterStrings(localized_strings, resources, arraysize(resources));
87 localized_strings->Set("avatarIcons", GetAvatarIcons().release());
90 void SupervisedUserImportHandler::InitializeHandler() {
91 Profile* profile = Profile::FromWebUI(web_ui());
92 if (!profile->IsSupervised()) {
93 SupervisedUserSyncService* sync_service =
94 SupervisedUserSyncServiceFactory::GetForProfile(profile);
95 if (sync_service) {
96 sync_service->AddObserver(this);
97 observer_.Add(ProfileOAuth2TokenServiceFactory::GetForProfile(profile)->
98 signin_error_controller());
99 SupervisedUserSharedSettingsService* settings_service =
100 SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
101 profile);
102 subscription_ = settings_service->Subscribe(
103 base::Bind(&SupervisedUserImportHandler::OnSharedSettingChanged,
104 weak_ptr_factory_.GetWeakPtr()));
105 } else {
106 DCHECK(!SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
107 profile));
108 DCHECK(!ProfileOAuth2TokenServiceFactory::GetForProfile(profile));
113 void SupervisedUserImportHandler::RegisterMessages() {
114 web_ui()->RegisterMessageCallback("requestSupervisedUserImportUpdate",
115 base::Bind(&SupervisedUserImportHandler::
116 RequestSupervisedUserImportUpdate,
117 base::Unretained(this)));
120 void SupervisedUserImportHandler::OnSupervisedUsersChanged() {
121 FetchSupervisedUsers();
124 void SupervisedUserImportHandler::FetchSupervisedUsers() {
125 web_ui()->CallJavascriptFunction(
126 "options.SupervisedUserListData.resetPromise");
127 RequestSupervisedUserImportUpdate(NULL);
130 void SupervisedUserImportHandler::RequestSupervisedUserImportUpdate(
131 const base::ListValue* /* args */) {
132 if (Profile::FromWebUI(web_ui())->IsSupervised())
133 return;
135 if (!IsAccountConnected() || HasAuthError()) {
136 ClearSupervisedUsersAndShowError();
137 } else {
138 SupervisedUserSyncService* supervised_user_sync_service =
139 SupervisedUserSyncServiceFactory::GetForProfile(
140 Profile::FromWebUI(web_ui()));
141 if (supervised_user_sync_service) {
142 supervised_user_sync_service->GetSupervisedUsersAsync(
143 base::Bind(&SupervisedUserImportHandler::SendExistingSupervisedUsers,
144 weak_ptr_factory_.GetWeakPtr()));
149 void SupervisedUserImportHandler::SendExistingSupervisedUsers(
150 const base::DictionaryValue* dict) {
151 DCHECK(dict);
152 const ProfileInfoCache& cache =
153 g_browser_process->profile_manager()->GetProfileInfoCache();
155 // Collect the ids of local supervised user profiles.
156 std::set<std::string> supervised_user_ids;
157 for (size_t i = 0; i < cache.GetNumberOfProfiles(); ++i) {
158 if (cache.ProfileIsSupervisedAtIndex(i))
159 supervised_user_ids.insert(cache.GetSupervisedUserIdOfProfileAtIndex(i));
162 base::ListValue supervised_users;
163 Profile* profile = Profile::FromWebUI(web_ui());
164 SupervisedUserSharedSettingsService* service =
165 SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(profile);
166 for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) {
167 const base::DictionaryValue* value = NULL;
168 bool success = it.value().GetAsDictionary(&value);
169 DCHECK(success);
170 std::string name;
171 value->GetString(SupervisedUserSyncService::kName, &name);
173 base::DictionaryValue* supervised_user = new base::DictionaryValue;
174 supervised_user->SetString("id", it.key());
175 supervised_user->SetString("name", name);
177 int avatar_index = SupervisedUserSyncService::kNoAvatar;
178 const base::Value* avatar_index_value =
179 service->GetValue(it.key(), supervised_users::kChromeAvatarIndex);
180 if (avatar_index_value) {
181 success = avatar_index_value->GetAsInteger(&avatar_index);
182 } else {
183 // Check if there is a legacy avatar index stored.
184 std::string avatar_str;
185 value->GetString(SupervisedUserSyncService::kChromeAvatar, &avatar_str);
186 success =
187 SupervisedUserSyncService::GetAvatarIndex(avatar_str, &avatar_index);
189 DCHECK(success);
190 supervised_user->SetBoolean(
191 "needAvatar",
192 avatar_index == SupervisedUserSyncService::kNoAvatar);
194 std::string supervised_user_icon =
195 std::string(chrome::kChromeUIThemeURL) +
196 "IDR_SUPERVISED_USER_PLACEHOLDER";
197 std::string avatar_url =
198 avatar_index == SupervisedUserSyncService::kNoAvatar ?
199 supervised_user_icon :
200 profiles::GetDefaultAvatarIconUrl(avatar_index);
201 supervised_user->SetString("iconURL", avatar_url);
202 bool on_current_device =
203 supervised_user_ids.find(it.key()) != supervised_user_ids.end();
204 supervised_user->SetBoolean("onCurrentDevice", on_current_device);
206 supervised_users.Append(supervised_user);
209 web_ui()->CallJavascriptFunction(
210 "options.SupervisedUserListData.receiveExistingSupervisedUsers",
211 supervised_users);
214 void SupervisedUserImportHandler::ClearSupervisedUsersAndShowError() {
215 web_ui()->CallJavascriptFunction(
216 "options.SupervisedUserListData.onSigninError");
219 bool SupervisedUserImportHandler::IsAccountConnected() const {
220 Profile* profile = Profile::FromWebUI(web_ui());
221 SigninManagerBase* signin_manager =
222 SigninManagerFactory::GetForProfile(profile);
223 return signin_manager && signin_manager->IsAuthenticated();
226 bool SupervisedUserImportHandler::HasAuthError() const {
227 Profile* profile = Profile::FromWebUI(web_ui());
228 ProfileOAuth2TokenService* token_service =
229 ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
230 if (!token_service)
231 return true;
233 SigninErrorController* error_controller =
234 token_service->signin_error_controller();
236 GoogleServiceAuthError::State state = error_controller->auth_error().state();
238 return state == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS ||
239 state == GoogleServiceAuthError::USER_NOT_SIGNED_UP ||
240 state == GoogleServiceAuthError::ACCOUNT_DELETED ||
241 state == GoogleServiceAuthError::ACCOUNT_DISABLED;
244 void SupervisedUserImportHandler::OnSharedSettingChanged(
245 const std::string& supervised_user_id,
246 const std::string& key) {
247 if (key == supervised_users::kChromeAvatarIndex)
248 FetchSupervisedUsers();
251 void SupervisedUserImportHandler::OnErrorChanged() {
252 FetchSupervisedUsers();
255 } // namespace options