summaryrefslogtreecommitdiffstats
path: root/chromium/chrome/browser/ui/webui/settings/chromeos
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-09-12 10:27:29 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-09-12 08:34:13 +0000
commit53d399fe6415a96ea6986ec0d402a9c07da72453 (patch)
treece7dbd5d170326a7d1c5f69f5dcd841c178e0dc0 /chromium/chrome/browser/ui/webui/settings/chromeos
parenta3ee7849e3b0ad3d5f9595fa1cfd694c22dcee2a (diff)
BASELINE: Update Chromium to 60.0.3112.116 and Ninja to 1.8.2
Also adds a few devtools and webui files needed for new features. Change-Id: I431976cc9f4c209d062a925ab6a5d63ec61abcfe Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/chrome/browser/ui/webui/settings/chromeos')
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc67
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h51
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc103
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h66
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc409
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h139
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc447
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h118
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc182
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.h78
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc82
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h67
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.cc51
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.h51
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc138
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h59
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc370
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h127
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc143
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.h63
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.cc160
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.h67
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler_unittest.cc264
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc327
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.h90
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc132
-rw-r--r--chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.h41
27 files changed, 3892 insertions, 0 deletions
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc
new file mode 100644
index 00000000000..a74053c73a4
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc
@@ -0,0 +1,67 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "chrome/browser/extensions/extension_tab_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/common/extensions/extension_constants.h"
+#include "content/public/browser/web_ui.h"
+#include "extensions/browser/extension_registry.h"
+
+namespace chromeos {
+namespace settings {
+
+AccessibilityHandler::AccessibilityHandler(content::WebUI* webui)
+ : profile_(Profile::FromWebUI(webui)) {
+}
+
+AccessibilityHandler::~AccessibilityHandler() {}
+
+void AccessibilityHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "showChromeVoxSettings",
+ base::Bind(&AccessibilityHandler::HandleShowChromeVoxSettings,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "showSelectToSpeakSettings",
+ base::Bind(&AccessibilityHandler::HandleShowSelectToSpeakSettings,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "showSwitchAccessSettings",
+ base::Bind(&AccessibilityHandler::HandleShowSwitchAccessSettings,
+ base::Unretained(this)));
+}
+
+void AccessibilityHandler::HandleShowChromeVoxSettings(
+ const base::ListValue* args) {
+ OpenExtensionOptionsPage(extension_misc::kChromeVoxExtensionId);
+}
+
+void AccessibilityHandler::HandleShowSelectToSpeakSettings(
+ const base::ListValue* args) {
+ OpenExtensionOptionsPage(extension_misc::kSelectToSpeakExtensionId);
+}
+
+void AccessibilityHandler::HandleShowSwitchAccessSettings(
+ const base::ListValue* args) {
+ OpenExtensionOptionsPage(extension_misc::kSwitchAccessExtensionId);
+}
+
+void AccessibilityHandler::OpenExtensionOptionsPage(const char extension_id[]) {
+ const extensions::Extension* extension =
+ extensions::ExtensionRegistry::Get(profile_)->GetExtensionById(
+ extension_id, extensions::ExtensionRegistry::ENABLED);
+ if (!extension)
+ return;
+ extensions::ExtensionTabUtil::OpenOptionsPage(
+ extension,
+ chrome::FindBrowserWithWebContents(web_ui()->GetWebContents()));
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h
new file mode 100644
index 00000000000..d03c83e2ea6
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.h
@@ -0,0 +1,51 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_ACCESSIBILITY_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_ACCESSIBILITY_HANDLER_H_
+
+#include "base/macros.h"
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+
+namespace base {
+class ListValue;
+}
+
+namespace content {
+class WebUI;
+}
+
+class Profile;
+
+namespace chromeos {
+namespace settings {
+
+class AccessibilityHandler : public ::settings::SettingsPageUIHandler {
+ public:
+ explicit AccessibilityHandler(content::WebUI* webui);
+ ~AccessibilityHandler() override;
+
+ // SettingsPageUIHandler implementation.
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override {}
+ void OnJavascriptDisallowed() override {}
+
+ private:
+ // Callback for the messages to show settings for ChromeVox,
+ // Select To Speak, or Switch Access.
+ void HandleShowChromeVoxSettings(const base::ListValue* args);
+ void HandleShowSelectToSpeakSettings(const base::ListValue* args);
+ void HandleShowSwitchAccessSettings(const base::ListValue* args);
+
+ void OpenExtensionOptionsPage(const char extension_id[]);
+
+ Profile* profile_; // Weak pointer.
+
+ DISALLOW_COPY_AND_ASSIGN(AccessibilityHandler);
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_ACCESSIBILITY_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc
new file mode 100644
index 00000000000..51e85cb3f92
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.cc
@@ -0,0 +1,103 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h"
+
+#include "base/values.h"
+#include "chrome/browser/chromeos/arc/arc_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/app_list/arc/arc_app_utils.h" // kSettingsAppId
+#include "ui/events/event_constants.h"
+
+namespace chromeos {
+namespace settings {
+
+AndroidAppsHandler::AndroidAppsHandler(Profile* profile)
+ : arc_prefs_observer_(this),
+ arc_session_manager_observer_(this),
+ profile_(profile),
+ weak_ptr_factory_(this) {}
+
+AndroidAppsHandler::~AndroidAppsHandler() {}
+
+void AndroidAppsHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "requestAndroidAppsInfo",
+ base::Bind(&AndroidAppsHandler::HandleRequestAndroidAppsInfo,
+ weak_ptr_factory_.GetWeakPtr()));
+ web_ui()->RegisterMessageCallback(
+ "showAndroidAppsSettings",
+ base::Bind(&AndroidAppsHandler::ShowAndroidAppsSettings,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void AndroidAppsHandler::OnJavascriptAllowed() {
+ ArcAppListPrefs* arc_prefs = ArcAppListPrefs::Get(profile_);
+ if (arc_prefs) {
+ arc_prefs_observer_.Add(arc_prefs);
+ // arc::ArcSessionManager is assosiated with primary profile.
+ arc_session_manager_observer_.Add(arc::ArcSessionManager::Get());
+ }
+}
+
+void AndroidAppsHandler::OnJavascriptDisallowed() {
+ arc_prefs_observer_.RemoveAll();
+ arc_session_manager_observer_.RemoveAll();
+}
+
+void AndroidAppsHandler::OnAppRegistered(
+ const std::string& app_id,
+ const ArcAppListPrefs::AppInfo& app_info) {
+ OnAppChanged(app_id);
+}
+
+void AndroidAppsHandler::OnAppRemoved(const std::string& app_id) {
+ OnAppChanged(app_id);
+}
+
+void AndroidAppsHandler::OnAppChanged(const std::string& app_id) {
+ if (app_id != arc::kSettingsAppId)
+ return;
+ SendAndroidAppsInfo();
+}
+
+void AndroidAppsHandler::OnArcPlayStoreEnabledChanged(bool enabled) {
+ SendAndroidAppsInfo();
+}
+
+std::unique_ptr<base::DictionaryValue>
+AndroidAppsHandler::BuildAndroidAppsInfo() {
+ std::unique_ptr<base::DictionaryValue> info(new base::DictionaryValue);
+ info->SetBoolean("playStoreEnabled",
+ arc::IsArcPlayStoreEnabledForProfile(profile_));
+ info->SetBoolean(
+ "settingsAppAvailable",
+ ArcAppListPrefs::Get(profile_)->IsRegistered(arc::kSettingsAppId));
+ return info;
+}
+
+void AndroidAppsHandler::HandleRequestAndroidAppsInfo(
+ const base::ListValue* args) {
+ SendAndroidAppsInfo();
+}
+
+void AndroidAppsHandler::SendAndroidAppsInfo() {
+ AllowJavascript();
+ std::unique_ptr<base::DictionaryValue> info = BuildAndroidAppsInfo();
+ FireWebUIListener("android-apps-info-update", *info);
+}
+
+void AndroidAppsHandler::ShowAndroidAppsSettings(const base::ListValue* args) {
+ CHECK_EQ(1U, args->GetSize());
+ bool activated_from_keyboard = false;
+ args->GetBoolean(0, &activated_from_keyboard);
+ int flags = activated_from_keyboard ? ui::EF_NONE : ui::EF_LEFT_MOUSE_BUTTON;
+
+ // Settings in secondary profile cannot access ARC.
+ CHECK(arc::IsArcAllowedForProfile(profile_));
+ arc::LaunchAndroidSettingsApp(profile_, flags);
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h
new file mode 100644
index 00000000000..62a530c4742
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/android_apps_handler.h
@@ -0,0 +1,66 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_ANDROID_APPS_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_ANDROID_APPS_HANDLER_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/scoped_observer.h"
+#include "chrome/browser/chromeos/arc/arc_session_manager.h"
+#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+
+class Profile;
+
+namespace base {
+class DictionaryValue;
+}
+
+namespace chromeos {
+namespace settings {
+
+class AndroidAppsHandler : public ::settings::SettingsPageUIHandler,
+ public ArcAppListPrefs::Observer,
+ public arc::ArcSessionManager::Observer {
+ public:
+ explicit AndroidAppsHandler(Profile* profile);
+ ~AndroidAppsHandler() override;
+
+ // SettingsPageUIHandler
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override;
+ void OnJavascriptDisallowed() override;
+
+ // ArcAppListPrefs::Observer
+ void OnAppRemoved(const std::string& app_id) override;
+ void OnAppRegistered(const std::string& app_id,
+ const ArcAppListPrefs::AppInfo& app_info) override;
+
+ // arc::ArcSessionManager::Observer:
+ void OnArcPlayStoreEnabledChanged(bool enabled) override;
+
+ private:
+ std::unique_ptr<base::DictionaryValue> BuildAndroidAppsInfo();
+ void OnAppChanged(const std::string& app_id);
+ void HandleRequestAndroidAppsInfo(const base::ListValue* args);
+ void SendAndroidAppsInfo();
+ void ShowAndroidAppsSettings(const base::ListValue* args);
+
+ ScopedObserver<ArcAppListPrefs, ArcAppListPrefs::Observer>
+ arc_prefs_observer_;
+ ScopedObserver<arc::ArcSessionManager, arc::ArcSessionManager::Observer>
+ arc_session_manager_observer_;
+ Profile* profile_; // unowned
+ base::WeakPtrFactory<AndroidAppsHandler> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(AndroidAppsHandler);
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_ANDROID_APPS_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
new file mode 100644
index 00000000000..378b08c4b00
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.cc
@@ -0,0 +1,409 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/command_line.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/path_service.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/browser/chrome_notification_types.h"
+#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
+#include "chrome/browser/chromeos/camera_presence_notifier.h"
+#include "chrome/browser/chromeos/login/users/avatar/user_image_manager.h"
+#include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
+#include "chrome/browser/chromeos/login/users/default_user_image/default_user_images.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/chrome_select_file_policy.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/grit/browser_resources.h"
+#include "chrome/grit/generated_resources.h"
+#include "chromeos/audio/chromeos_sounds.h"
+#include "components/user_manager/user.h"
+#include "components/user_manager/user_image/user_image.h"
+#include "components/user_manager/user_manager.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/web_ui.h"
+#include "content/public/common/url_constants.h"
+#include "media/audio/sounds/sounds_manager.h"
+#include "net/base/data_url.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/webui/web_ui_util.h"
+#include "ui/views/widget/widget.h"
+#include "url/gurl.h"
+
+using content::BrowserThread;
+
+namespace chromeos {
+namespace settings {
+
+namespace {
+
+// Returns info about extensions for files we support as user images.
+ui::SelectFileDialog::FileTypeInfo GetUserImageFileTypeInfo() {
+ ui::SelectFileDialog::FileTypeInfo file_type_info;
+ file_type_info.extensions.resize(1);
+
+ file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("bmp"));
+
+ file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("jpg"));
+ file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("jpeg"));
+
+ file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("png"));
+
+ file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("tif"));
+ file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("tiff"));
+
+ file_type_info.extension_description_overrides.resize(1);
+ file_type_info.extension_description_overrides[0] =
+ l10n_util::GetStringUTF16(IDS_IMAGE_FILES);
+
+ return file_type_info;
+}
+
+// Time histogram suffix for profile image download.
+const char kProfileDownloadReason[] = "Preferences";
+
+} // namespace
+
+ChangePictureHandler::ChangePictureHandler()
+ : previous_image_url_(url::kAboutBlankURL),
+ previous_image_index_(user_manager::User::USER_IMAGE_INVALID),
+ user_manager_observer_(this),
+ camera_observer_(this) {
+ ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
+ media::SoundsManager* manager = media::SoundsManager::Get();
+ manager->Initialize(SOUND_OBJECT_DELETE,
+ bundle.GetRawDataResource(IDR_SOUND_OBJECT_DELETE_WAV));
+ manager->Initialize(SOUND_CAMERA_SNAP,
+ bundle.GetRawDataResource(IDR_SOUND_CAMERA_SNAP_WAV));
+}
+
+ChangePictureHandler::~ChangePictureHandler() {
+ if (select_file_dialog_.get())
+ select_file_dialog_->ListenerDestroyed();
+}
+
+void ChangePictureHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "chooseFile", base::Bind(&ChangePictureHandler::HandleChooseFile,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "photoTaken", base::Bind(&ChangePictureHandler::HandlePhotoTaken,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "discardPhoto", base::Bind(&ChangePictureHandler::HandleDiscardPhoto,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "onChangePicturePageInitialized",
+ base::Bind(&ChangePictureHandler::HandlePageInitialized,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "selectImage", base::Bind(&ChangePictureHandler::HandleSelectImage,
+ base::Unretained(this)));
+}
+
+void ChangePictureHandler::OnJavascriptAllowed() {
+ user_manager_observer_.Add(user_manager::UserManager::Get());
+ camera_observer_.Add(CameraPresenceNotifier::GetInstance());
+}
+
+void ChangePictureHandler::OnJavascriptDisallowed() {
+ user_manager_observer_.Remove(user_manager::UserManager::Get());
+ camera_observer_.Remove(CameraPresenceNotifier::GetInstance());
+}
+
+void ChangePictureHandler::SendDefaultImages() {
+ base::ListValue image_urls;
+ for (int i = default_user_image::kFirstDefaultImageIndex;
+ i < default_user_image::kDefaultImagesCount; ++i) {
+ std::unique_ptr<base::DictionaryValue> image_data(
+ new base::DictionaryValue);
+ image_data->SetString("url", default_user_image::GetDefaultImageUrl(i));
+ image_data->SetString("author",
+ l10n_util::GetStringUTF16(
+ default_user_image::kDefaultImageAuthorIDs[i]));
+ image_data->SetString("website",
+ l10n_util::GetStringUTF16(
+ default_user_image::kDefaultImageWebsiteIDs[i]));
+ image_data->SetString("title",
+ default_user_image::GetDefaultImageDescription(i));
+ image_urls.Append(std::move(image_data));
+ }
+ FireWebUIListener("default-images-changed", image_urls);
+}
+
+void ChangePictureHandler::HandleChooseFile(const base::ListValue* args) {
+ DCHECK(args && args->empty());
+ select_file_dialog_ = ui::SelectFileDialog::Create(
+ this, new ChromeSelectFilePolicy(web_ui()->GetWebContents()));
+
+ base::FilePath downloads_path;
+ if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &downloads_path)) {
+ NOTREACHED();
+ return;
+ }
+
+ // Static so we initialize it only once.
+ CR_DEFINE_STATIC_LOCAL(ui::SelectFileDialog::FileTypeInfo, file_type_info,
+ (GetUserImageFileTypeInfo()));
+
+ select_file_dialog_->SelectFile(
+ ui::SelectFileDialog::SELECT_OPEN_FILE,
+ l10n_util::GetStringUTF16(IDS_DOWNLOAD_TITLE), downloads_path,
+ &file_type_info, 0, FILE_PATH_LITERAL(""), GetBrowserWindow(), NULL);
+}
+
+void ChangePictureHandler::HandleDiscardPhoto(const base::ListValue* args) {
+ DCHECK(args->empty());
+ AccessibilityManager::Get()->PlayEarcon(
+ SOUND_OBJECT_DELETE, PlaySoundOption::SPOKEN_FEEDBACK_ENABLED);
+}
+
+void ChangePictureHandler::HandlePhotoTaken(const base::ListValue* args) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ AccessibilityManager::Get()->PlayEarcon(
+ SOUND_CAMERA_SNAP, PlaySoundOption::SPOKEN_FEEDBACK_ENABLED);
+
+ std::string image_url;
+ if (!args || args->GetSize() != 1 || !args->GetString(0, &image_url))
+ NOTREACHED();
+ DCHECK(!image_url.empty());
+
+ std::string mime_type, charset, raw_data;
+ if (!net::DataURL::Parse(GURL(image_url), &mime_type, &charset, &raw_data))
+ NOTREACHED();
+ DCHECK_EQ("image/png", mime_type);
+
+ user_photo_ = gfx::ImageSkia();
+ user_photo_data_url_ = image_url;
+
+ ImageDecoder::Cancel(this);
+ ImageDecoder::Start(this, raw_data);
+}
+
+void ChangePictureHandler::HandlePageInitialized(const base::ListValue* args) {
+ DCHECK(args && args->empty());
+
+ AllowJavascript();
+
+ SendDefaultImages();
+ SendSelectedImage();
+ UpdateProfileImage();
+}
+
+void ChangePictureHandler::SendSelectedImage() {
+ const user_manager::User* user = GetUser();
+ DCHECK(user->GetAccountId().is_valid());
+
+ previous_image_index_ = user->image_index();
+ switch (previous_image_index_) {
+ case user_manager::User::USER_IMAGE_EXTERNAL: {
+ // User has image from camera/file, record it and add to the image list.
+ previous_image_ = user->GetImage();
+ SendOldImage(webui::GetBitmapDataUrl(*previous_image_.bitmap()));
+ break;
+ }
+ case user_manager::User::USER_IMAGE_PROFILE: {
+ // User has their Profile image as the current image.
+ SendProfileImage(user->GetImage(), true);
+ break;
+ }
+ default: {
+ DCHECK(previous_image_index_ >= 0 &&
+ previous_image_index_ < default_user_image::kDefaultImagesCount);
+ if (previous_image_index_ >=
+ default_user_image::kFirstDefaultImageIndex) {
+ // User has image from the current set of default images.
+ base::Value image_url(
+ default_user_image::GetDefaultImageUrl(previous_image_index_));
+ FireWebUIListener("selected-image-changed", image_url);
+ } else {
+ // User has an old default image, so present it in the same manner as a
+ // previous image from file.
+ SendOldImage(
+ default_user_image::GetDefaultImageUrl(previous_image_index_));
+ }
+ }
+ }
+}
+
+void ChangePictureHandler::SendProfileImage(const gfx::ImageSkia& image,
+ bool should_select) {
+ base::Value data_url(webui::GetBitmapDataUrl(*image.bitmap()));
+ base::Value select(should_select);
+ FireWebUIListener("profile-image-changed", data_url, select);
+}
+
+void ChangePictureHandler::UpdateProfileImage() {
+ UserImageManager* user_image_manager =
+ ChromeUserManager::Get()->GetUserImageManager(GetUser()->GetAccountId());
+ // If we have a downloaded profile image and haven't sent it in
+ // |SendSelectedImage|, send it now (without selecting).
+ if (previous_image_index_ != user_manager::User::USER_IMAGE_PROFILE &&
+ !user_image_manager->DownloadedProfileImage().isNull())
+ SendProfileImage(user_image_manager->DownloadedProfileImage(), false);
+
+ user_image_manager->DownloadProfileImage(kProfileDownloadReason);
+}
+
+void ChangePictureHandler::SendOldImage(const std::string& image_url) {
+ previous_image_url_ = image_url;
+ base::Value url(image_url);
+ FireWebUIListener("old-image-changed", url);
+}
+
+void ChangePictureHandler::HandleSelectImage(const base::ListValue* args) {
+ std::string image_url;
+ std::string image_type;
+ if (!args || args->GetSize() != 2 || !args->GetString(0, &image_url) ||
+ !args->GetString(1, &image_type)) {
+ NOTREACHED();
+ return;
+ }
+ // |image_url| may be empty unless |image_type| is "default".
+ DCHECK(!image_type.empty());
+
+ UserImageManager* user_image_manager =
+ ChromeUserManager::Get()->GetUserImageManager(GetUser()->GetAccountId());
+ int image_index = user_manager::User::USER_IMAGE_INVALID;
+ bool waiting_for_camera_photo = false;
+
+ if (image_type == "old") {
+ // Previous image (from camera or manually uploaded) re-selected.
+ DCHECK(!previous_image_.isNull());
+ user_image_manager->SaveUserImage(
+ user_manager::UserImage::CreateAndEncode(
+ previous_image_,
+ user_manager::UserImage::FORMAT_JPEG));
+
+ UMA_HISTOGRAM_EXACT_LINEAR("UserImage.ChangeChoice",
+ default_user_image::kHistogramImageOld,
+ default_user_image::kHistogramImagesCount);
+ VLOG(1) << "Selected old user image";
+ } else if (image_type == "default" &&
+ default_user_image::IsDefaultImageUrl(image_url, &image_index)) {
+ // One of the default user images.
+ user_image_manager->SaveUserDefaultImageIndex(image_index);
+
+ UMA_HISTOGRAM_EXACT_LINEAR(
+ "UserImage.ChangeChoice",
+ default_user_image::GetDefaultImageHistogramValue(image_index),
+ default_user_image::kHistogramImagesCount);
+ VLOG(1) << "Selected default user image: " << image_index;
+ } else if (image_type == "camera") {
+ // Camera image is selected.
+ if (user_photo_.isNull()) {
+ waiting_for_camera_photo = true;
+ VLOG(1) << "Still waiting for camera image to decode";
+ } else {
+ SetImageFromCamera(user_photo_);
+ }
+ } else if (image_type == "profile") {
+ // Profile image selected. Could be previous (old) user image.
+ user_image_manager->SaveUserImageFromProfileImage();
+
+ if (previous_image_index_ == user_manager::User::USER_IMAGE_PROFILE) {
+ UMA_HISTOGRAM_EXACT_LINEAR("UserImage.ChangeChoice",
+ default_user_image::kHistogramImageOld,
+ default_user_image::kHistogramImagesCount);
+ VLOG(1) << "Selected old (profile) user image";
+ } else {
+ UMA_HISTOGRAM_EXACT_LINEAR("UserImage.ChangeChoice",
+ default_user_image::kHistogramImageFromProfile,
+ default_user_image::kHistogramImagesCount);
+ VLOG(1) << "Selected profile image";
+ }
+ } else {
+ NOTREACHED() << "Unexpected image type: " << image_type;
+ }
+
+ // Ignore the result of the previous decoding if it's no longer needed.
+ if (!waiting_for_camera_photo)
+ ImageDecoder::Cancel(this);
+}
+
+void ChangePictureHandler::FileSelected(const base::FilePath& path,
+ int index,
+ void* params) {
+ ChromeUserManager::Get()
+ ->GetUserImageManager(GetUser()->GetAccountId())
+ ->SaveUserImageFromFile(path);
+ UMA_HISTOGRAM_EXACT_LINEAR("UserImage.ChangeChoice",
+ default_user_image::kHistogramImageFromFile,
+ default_user_image::kHistogramImagesCount);
+ VLOG(1) << "Selected image from file";
+}
+
+void ChangePictureHandler::SetImageFromCamera(const gfx::ImageSkia& photo) {
+ ChromeUserManager::Get()
+ ->GetUserImageManager(GetUser()->GetAccountId())
+ ->SaveUserImage(user_manager::UserImage::CreateAndEncode(
+ photo, user_manager::UserImage::FORMAT_JPEG));
+ UMA_HISTOGRAM_EXACT_LINEAR("UserImage.ChangeChoice",
+ default_user_image::kHistogramImageFromCamera,
+ default_user_image::kHistogramImagesCount);
+ VLOG(1) << "Selected camera photo";
+}
+
+void ChangePictureHandler::SetCameraPresent(bool present) {
+ FireWebUIListener("camera-presence-changed", base::Value(present));
+}
+
+void ChangePictureHandler::OnCameraPresenceCheckDone(bool is_camera_present) {
+ SetCameraPresent(is_camera_present);
+}
+
+void ChangePictureHandler::OnUserImageChanged(const user_manager::User& user) {
+ // Not initialized yet.
+ if (previous_image_index_ == user_manager::User::USER_IMAGE_INVALID)
+ return;
+ SendSelectedImage();
+}
+
+void ChangePictureHandler::OnUserProfileImageUpdated(
+ const user_manager::User& user,
+ const gfx::ImageSkia& profile_image) {
+ // User profile image has been updated.
+ SendProfileImage(profile_image, false);
+}
+
+gfx::NativeWindow ChangePictureHandler::GetBrowserWindow() const {
+ Browser* browser =
+ chrome::FindBrowserWithWebContents(web_ui()->GetWebContents());
+ return browser->window()->GetNativeWindow();
+}
+
+void ChangePictureHandler::OnImageDecoded(const SkBitmap& decoded_image) {
+ user_photo_ = gfx::ImageSkia::CreateFrom1xBitmap(decoded_image);
+ SetImageFromCamera(user_photo_);
+}
+
+void ChangePictureHandler::OnDecodeImageFailed() {
+ NOTREACHED() << "Failed to decode PNG image from WebUI";
+}
+
+const user_manager::User* ChangePictureHandler::GetUser() const {
+ Profile* profile = Profile::FromWebUI(web_ui());
+ const user_manager::User* user =
+ ProfileHelper::Get()->GetUserByProfile(profile);
+ if (!user)
+ return user_manager::UserManager::Get()->GetActiveUser();
+ return user;
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h
new file mode 100644
index 00000000000..a213282241e
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/change_picture_handler.h
@@ -0,0 +1,139 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CHANGE_PICTURE_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CHANGE_PICTURE_HANDLER_H_
+
+#include "base/macros.h"
+#include "base/scoped_observer.h"
+#include "chrome/browser/chromeos/camera_presence_notifier.h"
+#include "chrome/browser/image_decoder.h"
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "components/user_manager/user_manager.h"
+#include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/shell_dialogs/select_file_dialog.h"
+
+namespace base {
+class ListValue;
+}
+
+namespace user_manager {
+class User;
+}
+
+namespace chromeos {
+
+namespace settings {
+
+// ChromeOS user image settings page UI handler.
+class ChangePictureHandler : public ::settings::SettingsPageUIHandler,
+ public ui::SelectFileDialog::Listener,
+ public user_manager::UserManager::Observer,
+ public ImageDecoder::ImageRequest,
+ public CameraPresenceNotifier::Observer {
+ public:
+ ChangePictureHandler();
+ ~ChangePictureHandler() override;
+
+ // WebUIMessageHandler implementation.
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override;
+ void OnJavascriptDisallowed() override;
+
+ // CameraPresenceNotifier::Observer implementation:
+ void OnCameraPresenceCheckDone(bool is_camera_present) override;
+
+ private:
+ // Sends list of available default images to the page.
+ void SendDefaultImages();
+
+ // Sends current selection to the page.
+ void SendSelectedImage();
+
+ // Sends the profile image to the page. If |should_select| is true then
+ // the profile image element is selected.
+ void SendProfileImage(const gfx::ImageSkia& image, bool should_select);
+
+ // Starts profile image update and shows the last downloaded profile image,
+ // if any, on the page. Shouldn't be called before |SendProfileImage|.
+ void UpdateProfileImage();
+
+ // Sends previous user image to the page.
+ void SendOldImage(const std::string& image_url);
+
+ // Starts camera presence check.
+ void CheckCameraPresence();
+
+ // Updates UI with camera presence state.
+ void SetCameraPresent(bool present);
+
+ // Opens a file selection dialog to choose user image from file.
+ void HandleChooseFile(const base::ListValue* args);
+
+ // Handles photo taken with WebRTC UI.
+ void HandlePhotoTaken(const base::ListValue* args);
+
+ // Handles 'discard-photo' button click.
+ void HandleDiscardPhoto(const base::ListValue* args);
+
+ // Gets the list of available user images and sends it to the page.
+ void HandleGetAvailableImages(const base::ListValue* args);
+
+ // Handles page initialized event.
+ void HandlePageInitialized(const base::ListValue* args);
+
+ // Selects one of the available images as user's.
+ void HandleSelectImage(const base::ListValue* args);
+
+ // SelectFileDialog::Delegate implementation.
+ void FileSelected(const base::FilePath& path,
+ int index,
+ void* params) override;
+
+ // user_manager::UserManager::Observer implementation.
+ void OnUserImageChanged(const user_manager::User& user) override;
+ void OnUserProfileImageUpdated(const user_manager::User& user,
+ const gfx::ImageSkia& profile_image) override;
+
+ // Sets user image to photo taken from camera.
+ void SetImageFromCamera(const gfx::ImageSkia& photo);
+
+ // Returns handle to browser window or NULL if it can't be found.
+ gfx::NativeWindow GetBrowserWindow() const;
+
+ // Overriden from ImageDecoder::ImageRequest:
+ void OnImageDecoded(const SkBitmap& decoded_image) override;
+ void OnDecodeImageFailed() override;
+
+ // Returns user related to current WebUI. If this user doesn't exist,
+ // returns active user.
+ const user_manager::User* GetUser() const;
+
+ scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
+
+ // Previous user image from camera/file and its data URL.
+ gfx::ImageSkia previous_image_;
+ std::string previous_image_url_;
+
+ // Index of the previous user image.
+ int previous_image_index_;
+
+ // Last user photo, if taken.
+ gfx::ImageSkia user_photo_;
+
+ // Data URL for |user_photo_|.
+ std::string user_photo_data_url_;
+
+ ScopedObserver<user_manager::UserManager, ChangePictureHandler>
+ user_manager_observer_;
+ ScopedObserver<CameraPresenceNotifier, ChangePictureHandler> camera_observer_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChangePictureHandler);
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CHANGE_PICTURE_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
new file mode 100644
index 00000000000..e5d02eb7315
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.cc
@@ -0,0 +1,447 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/files/file_util.h"
+#include "base/json/json_string_value_serializer.h"
+#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/path_service.h"
+#include "base/strings/string_util.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "base/values.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/printing/ppd_provider_factory.h"
+#include "chrome/browser/chromeos/printing/printer_configurer.h"
+#include "chrome/browser/chromeos/printing/printer_discoverer.h"
+#include "chrome/browser/chromeos/printing/printers_manager_factory.h"
+#include "chrome/browser/download/download_prefs.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/chrome_select_file_policy.h"
+#include "chrome/common/chrome_paths.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/debug_daemon_client.h"
+#include "chromeos/printing/ppd_cache.h"
+#include "chromeos/printing/ppd_provider.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_ui.h"
+#include "google_apis/google_api_keys.h"
+#include "net/base/filename_util.h"
+#include "net/url_request/url_request_context_getter.h"
+#include "printing/backend/print_backend.h"
+#include "url/third_party/mozilla/url_parse.h"
+
+namespace chromeos {
+namespace settings {
+
+namespace {
+
+// These values are written to logs. New enum values can be added, but existing
+// enums must never be renumbered or deleted and reused.
+enum PpdSourceForHistogram { kUser = 0, kScs = 1, kPpdSourceMax };
+
+void RecordPpdSource(const PpdSourceForHistogram& source) {
+ UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PpdSource", source, kPpdSourceMax);
+}
+
+void OnRemovedPrinter(const Printer::PrinterProtocol& protocol, bool success) {
+ UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterRemoved", protocol,
+ Printer::PrinterProtocol::kProtocolMax);
+}
+
+std::unique_ptr<base::DictionaryValue> GetPrinterInfo(const Printer& printer) {
+ std::unique_ptr<base::DictionaryValue> printer_info =
+ base::MakeUnique<base::DictionaryValue>();
+ printer_info->SetString("printerId", printer.id());
+ printer_info->SetString("printerName", printer.display_name());
+ printer_info->SetString("printerDescription", printer.description());
+ printer_info->SetString("printerManufacturer", printer.manufacturer());
+ printer_info->SetString("printerModel", printer.model());
+ // Get protocol, ip address and queue from the printer's URI.
+ const std::string printer_uri = printer.uri();
+ url::Parsed parsed;
+ url::ParseStandardURL(printer_uri.c_str(), printer_uri.length(), &parsed);
+
+ std::string scheme;
+ std::string host;
+ std::string path;
+ if (parsed.scheme.len > 0)
+ scheme = std::string(printer_uri, parsed.scheme.begin, parsed.scheme.len);
+ if (parsed.host.len > 0)
+ host = std::string(printer_uri, parsed.host.begin, parsed.host.len);
+ if (parsed.path.len > 0)
+ path = std::string(printer_uri, parsed.path.begin, parsed.path.len);
+ if (base::ToLowerASCII(scheme) == "usb") {
+ // USB has URI path (and, maybe, query) components that aren't really
+ // associated with a queue -- the mapping between printing semantics and URI
+ // semantics breaks down a bit here. From the user's point of view, the
+ // entire host/path/query block is the printer address for USB.
+ printer_info->SetString("printerAddress",
+ printer_uri.substr(parsed.host.begin));
+ } else {
+ printer_info->SetString("printerAddress", host);
+ if (!path.empty()) {
+ printer_info->SetString("printerQueue", path.substr(1));
+ }
+ }
+ printer_info->SetString("printerProtocol", base::ToLowerASCII(scheme));
+
+ return printer_info;
+}
+
+} // namespace
+
+CupsPrintersHandler::CupsPrintersHandler(content::WebUI* webui)
+ : printer_discoverer_(nullptr),
+ profile_(Profile::FromWebUI(webui)),
+ weak_factory_(this) {
+ ppd_provider_ = printing::CreateProvider(profile_);
+ printer_configurer_ = chromeos::PrinterConfigurer::Create(profile_);
+}
+
+CupsPrintersHandler::~CupsPrintersHandler() {}
+
+void CupsPrintersHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "getCupsPrintersList",
+ base::Bind(&CupsPrintersHandler::HandleGetCupsPrintersList,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "updateCupsPrinter",
+ base::Bind(&CupsPrintersHandler::HandleUpdateCupsPrinter,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "removeCupsPrinter",
+ base::Bind(&CupsPrintersHandler::HandleRemoveCupsPrinter,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "addCupsPrinter", base::Bind(&CupsPrintersHandler::HandleAddCupsPrinter,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "getCupsPrinterManufacturersList",
+ base::Bind(&CupsPrintersHandler::HandleGetCupsPrinterManufacturers,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "getCupsPrinterModelsList",
+ base::Bind(&CupsPrintersHandler::HandleGetCupsPrinterModels,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "selectPPDFile", base::Bind(&CupsPrintersHandler::HandleSelectPPDFile,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "startDiscoveringPrinters",
+ base::Bind(&CupsPrintersHandler::HandleStartDiscovery,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "stopDiscoveringPrinters",
+ base::Bind(&CupsPrintersHandler::HandleStopDiscovery,
+ base::Unretained(this)));
+}
+
+void CupsPrintersHandler::HandleGetCupsPrintersList(
+ const base::ListValue* args) {
+ AllowJavascript();
+
+ CHECK_EQ(1U, args->GetSize());
+ std::string callback_id;
+ CHECK(args->GetString(0, &callback_id));
+
+ std::vector<std::unique_ptr<Printer>> printers =
+ PrintersManagerFactory::GetForBrowserContext(profile_)->GetPrinters();
+
+ auto printers_list = base::MakeUnique<base::ListValue>();
+ for (const std::unique_ptr<Printer>& printer : printers) {
+ std::unique_ptr<base::DictionaryValue> printer_info =
+ GetPrinterInfo(*printer.get());
+ printers_list->Append(std::move(printer_info));
+ }
+
+ auto response = base::MakeUnique<base::DictionaryValue>();
+ response->Set("printerList", std::move(printers_list));
+ ResolveJavascriptCallback(base::Value(callback_id), *response);
+}
+
+void CupsPrintersHandler::HandleUpdateCupsPrinter(const base::ListValue* args) {
+ std::string printer_id;
+ std::string printer_name;
+ CHECK(args->GetString(0, &printer_id));
+ CHECK(args->GetString(1, &printer_name));
+
+ std::unique_ptr<Printer> printer = base::MakeUnique<Printer>(printer_id);
+ printer->set_display_name(printer_name);
+ PrintersManagerFactory::GetForBrowserContext(profile_)->RegisterPrinter(
+ std::move(printer));
+}
+
+void CupsPrintersHandler::HandleRemoveCupsPrinter(const base::ListValue* args) {
+ std::string printer_id;
+ std::string printer_name;
+ CHECK(args->GetString(0, &printer_id));
+ CHECK(args->GetString(1, &printer_name));
+ PrintersManager* prefs =
+ PrintersManagerFactory::GetForBrowserContext(profile_);
+ auto printer = prefs->GetPrinter(printer_id);
+ if (!printer)
+ return;
+
+ Printer::PrinterProtocol protocol = printer->GetProtocol();
+ prefs->RemovePrinter(printer_id);
+
+ chromeos::DebugDaemonClient* client =
+ chromeos::DBusThreadManager::Get()->GetDebugDaemonClient();
+ client->CupsRemovePrinter(printer_name,
+ base::Bind(&OnRemovedPrinter, protocol),
+ base::Bind(&base::DoNothing));
+}
+
+void CupsPrintersHandler::HandleAddCupsPrinter(const base::ListValue* args) {
+ AllowJavascript();
+
+ const base::DictionaryValue* printer_dict = nullptr;
+ CHECK(args->GetDictionary(0, &printer_dict));
+
+ std::string printer_id;
+ std::string printer_name;
+ std::string printer_description;
+ std::string printer_manufacturer;
+ std::string printer_model;
+ std::string printer_address;
+ std::string printer_protocol;
+ std::string printer_queue;
+ std::string printer_ppd_path;
+ CHECK(printer_dict->GetString("printerId", &printer_id));
+ CHECK(printer_dict->GetString("printerName", &printer_name));
+ CHECK(printer_dict->GetString("printerDescription", &printer_description));
+ CHECK(printer_dict->GetString("printerManufacturer", &printer_manufacturer));
+ CHECK(printer_dict->GetString("printerModel", &printer_model));
+ CHECK(printer_dict->GetString("printerAddress", &printer_address));
+ CHECK(printer_dict->GetString("printerProtocol", &printer_protocol));
+ // printerQueue might be null for a printer whose protocol is not 'LPD'.
+ printer_dict->GetString("printerQueue", &printer_queue);
+
+ // printerPPDPath might be null for an auto-discovered printer.
+ printer_dict->GetString("printerPPDPath", &printer_ppd_path);
+ std::string printer_uri = printer_protocol + "://" + printer_address;
+ if (!printer_queue.empty()) {
+ printer_uri += "/" + printer_queue;
+ }
+
+ std::unique_ptr<Printer> printer = base::MakeUnique<Printer>(printer_id);
+ printer->set_display_name(printer_name);
+ printer->set_description(printer_description);
+ printer->set_manufacturer(printer_manufacturer);
+ printer->set_model(printer_model);
+ printer->set_uri(printer_uri);
+
+ // Verify a valid ppd path is present.
+ if (!printer_ppd_path.empty()) {
+ RecordPpdSource(kUser);
+ GURL tmp = net::FilePathToFileURL(base::FilePath(printer_ppd_path));
+ if (!tmp.is_valid()) {
+ LOG(ERROR) << "Invalid ppd path: " << printer_ppd_path;
+ OnAddPrinterError();
+ return;
+ }
+ printer->mutable_ppd_reference()->user_supplied_ppd_url = tmp.spec();
+ } else if (!printer_manufacturer.empty() && !printer_model.empty()) {
+ RecordPpdSource(kScs);
+ // Using the manufacturer and model, get a ppd reference.
+ if (!ppd_provider_->GetPpdReference(printer_manufacturer, printer_model,
+ printer->mutable_ppd_reference())) {
+ LOG(ERROR) << "Failed to get ppd reference";
+ OnAddPrinterError();
+ return;
+ }
+ }
+
+ // Copy the printer for the configurer. Ownership needs to be transfered to
+ // the receiver of the callback.
+ const Printer printer_copy = *printer;
+ printer_configurer_->SetUpPrinter(
+ printer_copy,
+ base::Bind(&CupsPrintersHandler::OnAddedPrinter,
+ weak_factory_.GetWeakPtr(), base::Passed(&printer)));
+}
+
+void CupsPrintersHandler::OnAddedPrinter(
+ std::unique_ptr<Printer> printer,
+ chromeos::PrinterSetupResult result_code) {
+ std::string printer_name = printer->display_name();
+ UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterSetupResult", result_code,
+ chromeos::PrinterSetupResult::kMaxValue);
+ switch (result_code) {
+ case chromeos::PrinterSetupResult::kSuccess: {
+ UMA_HISTOGRAM_ENUMERATION("Printing.CUPS.PrinterAdded",
+ printer->GetProtocol(), Printer::kProtocolMax);
+ auto* manager = PrintersManagerFactory::GetForBrowserContext(profile_);
+ manager->PrinterInstalled(*printer);
+ manager->RegisterPrinter(std::move(printer));
+ break;
+ }
+ case chromeos::PrinterSetupResult::kPpdNotFound:
+ LOG(WARNING) << "Could not locate requested PPD";
+ break;
+ case chromeos::PrinterSetupResult::kPpdTooLarge:
+ LOG(WARNING) << "PPD is too large";
+ break;
+ case chromeos::PrinterSetupResult::kPpdUnretrievable:
+ LOG(WARNING) << "Could not retrieve PPD from server";
+ break;
+ case chromeos::PrinterSetupResult::kInvalidPpd:
+ LOG(WARNING) << "Provided PPD is invalid.";
+ break;
+ case chromeos::PrinterSetupResult::kPrinterUnreachable:
+ LOG(WARNING) << "Could not contact printer for configuration";
+ break;
+ case chromeos::PrinterSetupResult::kDbusError:
+ case chromeos::PrinterSetupResult::kFatalError:
+ LOG(ERROR) << "Unrecoverable error. Reboot required.";
+ break;
+ case chromeos::PrinterSetupResult::kMaxValue:
+ NOTREACHED() << "This is not an expected value";
+ break;
+ }
+ CallJavascriptFunction(
+ "cr.webUIListenerCallback", base::Value("on-add-cups-printer"),
+ base::Value(result_code == chromeos::PrinterSetupResult::kSuccess),
+ base::Value(printer_name));
+}
+
+void CupsPrintersHandler::OnAddPrinterError() {
+ FireWebUIListener("on-add-cups-printer", base::Value(false), base::Value(""));
+}
+
+void CupsPrintersHandler::HandleGetCupsPrinterManufacturers(
+ const base::ListValue* args) {
+ AllowJavascript();
+ std::string js_callback;
+ CHECK_EQ(1U, args->GetSize());
+ CHECK(args->GetString(0, &js_callback));
+ ppd_provider_->ResolveManufacturers(
+ base::Bind(&CupsPrintersHandler::ResolveManufacturersDone,
+ weak_factory_.GetWeakPtr(), js_callback));
+}
+
+void CupsPrintersHandler::HandleGetCupsPrinterModels(
+ const base::ListValue* args) {
+ AllowJavascript();
+ std::string js_callback;
+ std::string manufacturer;
+ CHECK_EQ(2U, args->GetSize());
+ CHECK(args->GetString(0, &js_callback));
+ CHECK(args->GetString(1, &manufacturer));
+
+ // Empty manufacturer queries may be triggered as a part of the ui
+ // initialization, and should just return empty results.
+ if (manufacturer.empty()) {
+ base::DictionaryValue response;
+ response.SetBoolean("success", true);
+ response.Set("models", base::MakeUnique<base::ListValue>());
+ ResolveJavascriptCallback(base::Value(js_callback), response);
+ return;
+ }
+
+ ppd_provider_->ResolvePrinters(
+ manufacturer, base::Bind(&CupsPrintersHandler::ResolvePrintersDone,
+ weak_factory_.GetWeakPtr(), js_callback));
+}
+
+void CupsPrintersHandler::HandleSelectPPDFile(const base::ListValue* args) {
+ CHECK_EQ(1U, args->GetSize());
+ CHECK(args->GetString(0, &webui_callback_id_));
+
+ base::FilePath downloads_path =
+ DownloadPrefs::FromDownloadManager(
+ content::BrowserContext::GetDownloadManager(profile_))
+ ->DownloadPath();
+
+ select_file_dialog_ = ui::SelectFileDialog::Create(
+ this, new ChromeSelectFilePolicy(web_ui()->GetWebContents()));
+ gfx::NativeWindow owning_window =
+ chrome::FindBrowserWithWebContents(web_ui()->GetWebContents())
+ ->window()
+ ->GetNativeWindow();
+ select_file_dialog_->SelectFile(
+ ui::SelectFileDialog::SELECT_OPEN_FILE, base::string16(), downloads_path,
+ nullptr, 0, FILE_PATH_LITERAL(""), owning_window, nullptr);
+}
+
+void CupsPrintersHandler::ResolveManufacturersDone(
+ const std::string& js_callback,
+ chromeos::printing::PpdProvider::CallbackResultCode result_code,
+ const std::vector<std::string>& manufacturers) {
+ auto manufacturers_value = base::MakeUnique<base::ListValue>();
+ if (result_code == chromeos::printing::PpdProvider::SUCCESS) {
+ manufacturers_value->AppendStrings(manufacturers);
+ }
+ base::DictionaryValue response;
+ response.SetBoolean("success",
+ result_code == chromeos::printing::PpdProvider::SUCCESS);
+ response.Set("manufacturers", std::move(manufacturers_value));
+ ResolveJavascriptCallback(base::Value(js_callback), response);
+}
+
+void CupsPrintersHandler::ResolvePrintersDone(
+ const std::string& js_callback,
+ chromeos::printing::PpdProvider::CallbackResultCode result_code,
+ const std::vector<std::string>& printers) {
+ auto printers_value = base::MakeUnique<base::ListValue>();
+ if (result_code == chromeos::printing::PpdProvider::SUCCESS) {
+ printers_value->AppendStrings(printers);
+ }
+ base::DictionaryValue response;
+ response.SetBoolean("success",
+ result_code == chromeos::printing::PpdProvider::SUCCESS);
+ response.Set("models", std::move(printers_value));
+ ResolveJavascriptCallback(base::Value(js_callback), response);
+}
+
+void CupsPrintersHandler::FileSelected(const base::FilePath& path,
+ int index,
+ void* params) {
+ DCHECK(!webui_callback_id_.empty());
+ ResolveJavascriptCallback(base::Value(webui_callback_id_),
+ base::Value(path.value()));
+ webui_callback_id_.clear();
+}
+
+void CupsPrintersHandler::HandleStartDiscovery(const base::ListValue* args) {
+ if (!printer_discoverer_.get()) {
+ printer_discoverer_ =
+ chromeos::PrinterDiscoverer::CreateForProfile(profile_);
+ }
+
+ printer_discoverer_->AddObserver(this);
+}
+
+void CupsPrintersHandler::HandleStopDiscovery(const base::ListValue* args) {
+ printer_discoverer_.reset();
+}
+
+void CupsPrintersHandler::OnPrintersFound(
+ const std::vector<Printer>& printers) {
+ std::unique_ptr<base::ListValue> printers_list =
+ base::MakeUnique<base::ListValue>();
+ for (const auto& printer : printers) {
+ printers_list->Append(GetPrinterInfo(printer));
+ }
+
+ FireWebUIListener("on-printer-discovered", *printers_list);
+}
+
+void CupsPrintersHandler::OnDiscoveryInitialScanDone(int printer_count) {
+ UMA_HISTOGRAM_COUNTS_100("Printing.CUPS.PrintersDiscovered", printer_count);
+ FireWebUIListener("on-printer-discovery-done");
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h
new file mode 100644
index 00000000000..343daeab6df
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/cups_printers_handler.h
@@ -0,0 +1,118 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CUPS_PRINTERS_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CUPS_PRINTERS_HANDLER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/files/file_path.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/chromeos/printing/printer_configurer.h"
+#include "chrome/browser/chromeos/printing/printer_discoverer.h"
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "chromeos/printing/ppd_provider.h"
+#include "chromeos/printing/printer_configuration.h"
+#include "ui/shell_dialogs/select_file_dialog.h"
+
+namespace base {
+class ListValue;
+} // namespace base
+
+class Profile;
+
+namespace chromeos {
+namespace printing {
+class PpdProvider;
+}
+namespace settings {
+
+// Chrome OS CUPS printing settings page UI handler.
+class CupsPrintersHandler : public ::settings::SettingsPageUIHandler,
+ public ui::SelectFileDialog::Listener,
+ public chromeos::PrinterDiscoverer::Observer {
+ public:
+ explicit CupsPrintersHandler(content::WebUI* webui);
+ ~CupsPrintersHandler() override;
+
+ // SettingsPageUIHandler overrides:
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override {}
+ void OnJavascriptDisallowed() override {}
+
+ private:
+ // Gets all CUPS printers and return it to WebUI.
+ void HandleGetCupsPrintersList(const base::ListValue* args);
+ void HandleUpdateCupsPrinter(const base::ListValue* args);
+ void HandleRemoveCupsPrinter(const base::ListValue* args);
+
+ void HandleAddCupsPrinter(const base::ListValue* args);
+ void OnAddedPrinter(std::unique_ptr<Printer> printer,
+ chromeos::PrinterSetupResult result);
+ void OnAddPrinterError();
+
+ // Get a list of all manufacturers for which we have at least one model of
+ // printer supported. Takes one argument, the callback id for the result.
+ // The callback will be invoked with {success: <boolean>, models:
+ // <Array<string>>}.
+ void HandleGetCupsPrinterManufacturers(const base::ListValue* args);
+
+ // Given a manufacturer, get a list of all models of printers for which we can
+ // get drivers. Takes two arguments - the callback id and the manufacturer
+ // name for which we want to list models. The callback will be called with
+ // {success: <boolean>, models: Array<string>}.
+ void HandleGetCupsPrinterModels(const base::ListValue* args);
+
+ void HandleSelectPPDFile(const base::ListValue* args);
+
+ // PpdProvider callback handlers.
+ void ResolveManufacturersDone(
+ const std::string& js_callback,
+ chromeos::printing::PpdProvider::CallbackResultCode result_code,
+ const std::vector<std::string>& available);
+ void ResolvePrintersDone(
+ const std::string& js_callback,
+ chromeos::printing::PpdProvider::CallbackResultCode result_code,
+ const std::vector<std::string>& available);
+
+ // ui::SelectFileDialog::Listener override:
+ void FileSelected(const base::FilePath& path,
+ int index,
+ void* params) override;
+
+ void HandleStartDiscovery(const base::ListValue* args);
+ void HandleStopDiscovery(const base::ListValue* args);
+
+ // chromeos::PrinterDiscoverer::Observer override:
+ void OnPrintersFound(const std::vector<Printer>& printers) override;
+ void OnDiscoveryInitialScanDone(int printer_count) override;
+
+ // Invokes debugd to add the printer to CUPS. If |ipp_everywhere| is true,
+ // automatic configuration will be attempted and |ppd_path| is ignored.
+ // |ppd_path| is the path to a Postscript Printer Description file that will
+ // be used to configure the printer capabilities. This file must be in
+ // Downloads or the PPD Cache.
+ void AddPrinterToCups(std::unique_ptr<Printer> printer,
+ const base::FilePath& ppd_path,
+ bool ipp_everywhere);
+
+ std::unique_ptr<chromeos::PrinterDiscoverer> printer_discoverer_;
+ scoped_refptr<chromeos::printing::PpdProvider> ppd_provider_;
+ std::unique_ptr<chromeos::PrinterConfigurer> printer_configurer_;
+
+ Profile* profile_;
+ scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
+ std::string webui_callback_id_;
+
+ base::WeakPtrFactory<CupsPrintersHandler> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(CupsPrintersHandler);
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_CUPS_PRINTERS_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc
new file mode 100644
index 00000000000..2562de268c0
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.cc
@@ -0,0 +1,182 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/date_time_handler.h"
+
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/values.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
+#include "chrome/browser/chromeos/set_time_dialog.h"
+#include "chrome/browser/chromeos/system/timezone_resolver_manager.h"
+#include "chrome/browser/chromeos/system/timezone_util.h"
+#include "chrome/common/pref_names.h"
+#include "chromeos/chromeos_switches.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/system_clock_client.h"
+#include "chromeos/settings/timezone_settings.h"
+#include "components/prefs/pref_service.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_ui.h"
+#include "content/public/browser/web_ui_data_source.h"
+
+namespace chromeos {
+namespace settings {
+
+namespace {
+
+// Returns whether the system time zone automatic detection policy is disabled
+// by a flag.
+bool IsSystemTimezoneAutomaticDetectionPolicyFlagDisabled() {
+ return base::CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDisableSystemTimezoneAutomaticDetectionPolicy);
+}
+
+// Returns whether the system's automatic time zone detection setting is
+// managed, which may override the user's setting.
+bool IsSystemTimezoneAutomaticDetectionManaged() {
+ if (IsSystemTimezoneAutomaticDetectionPolicyFlagDisabled())
+ return false;
+
+ return g_browser_process->local_state()->IsManagedPreference(
+ prefs::kSystemTimezoneAutomaticDetectionPolicy);
+}
+
+// Returns the system's automatic time zone detection policy value, which
+// corresponds to the SystemTimezoneProto's AutomaticTimezoneDetectionType
+// enum and determines whether the user's setting will be overridden.
+int GetSystemTimezoneAutomaticDetectionPolicyValue() {
+ DCHECK(IsSystemTimezoneAutomaticDetectionManaged());
+
+ return g_browser_process->local_state()->GetInteger(
+ prefs::kSystemTimezoneAutomaticDetectionPolicy);
+}
+
+// Returns whether the user can set the automatic detection setting, based on
+// flags and policies.
+bool IsTimezoneAutomaticDetectionUserEditable() {
+ if (system::HasSystemTimezonePolicy())
+ return false;
+
+ if (IsSystemTimezoneAutomaticDetectionManaged()) {
+ return GetSystemTimezoneAutomaticDetectionPolicyValue() ==
+ enterprise_management::SystemTimezoneProto::USERS_DECIDE;
+ }
+
+ return true;
+}
+
+} // namespace
+
+DateTimeHandler::DateTimeHandler()
+ : scoped_observer_(this), weak_ptr_factory_(this) {}
+
+DateTimeHandler::~DateTimeHandler() = default;
+
+DateTimeHandler* DateTimeHandler::Create(
+ content::WebUIDataSource* html_source) {
+ // Set the initial time zone to show.
+ html_source->AddString("timeZoneName", system::GetCurrentTimezoneName());
+ html_source->AddString(
+ "timeZoneID",
+ system::TimezoneSettings::GetInstance()->GetCurrentTimezoneID());
+
+ if (!IsTimezoneAutomaticDetectionUserEditable()) {
+ html_source->AddBoolean("timeZoneAutoDetectValueFromPolicy",
+ g_browser_process->platform_part()
+ ->GetTimezoneResolverManager()
+ ->ShouldApplyResolvedTimezone());
+ }
+
+ return new DateTimeHandler;
+}
+
+void DateTimeHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "dateTimePageReady", base::Bind(&DateTimeHandler::HandleDateTimePageReady,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "getTimeZones",
+ base::Bind(&DateTimeHandler::HandleGetTimeZones, base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "showSetDateTimeUI", base::Bind(&DateTimeHandler::HandleShowSetDateTimeUI,
+ base::Unretained(this)));
+}
+
+void DateTimeHandler::OnJavascriptAllowed() {
+ SystemClockClient* system_clock_client =
+ DBusThreadManager::Get()->GetSystemClockClient();
+ scoped_observer_.Add(system_clock_client);
+ SystemClockCanSetTimeChanged(system_clock_client->CanSetTime());
+
+ // The system time zone policy disables auto-detection entirely. (However,
+ // the time zone policy does not override the user's time zone itself.)
+ system_timezone_policy_subscription_ =
+ CrosSettings::Get()->AddSettingsObserver(
+ kSystemTimezonePolicy,
+ base::Bind(&DateTimeHandler::NotifyTimezoneAutomaticDetectionPolicy,
+ weak_ptr_factory_.GetWeakPtr()));
+
+ if (IsSystemTimezoneAutomaticDetectionPolicyFlagDisabled())
+ return;
+
+ // The auto-detection policy can force auto-detection on or off.
+ local_state_pref_change_registrar_.Init(g_browser_process->local_state());
+ local_state_pref_change_registrar_.Add(
+ prefs::kSystemTimezoneAutomaticDetectionPolicy,
+ base::Bind(&DateTimeHandler::NotifyTimezoneAutomaticDetectionPolicy,
+ base::Unretained(this)));
+}
+
+void DateTimeHandler::OnJavascriptDisallowed() {
+ scoped_observer_.RemoveAll();
+ system_timezone_policy_subscription_.reset();
+
+ if (!IsSystemTimezoneAutomaticDetectionPolicyFlagDisabled())
+ local_state_pref_change_registrar_.RemoveAll();
+}
+
+void DateTimeHandler::HandleDateTimePageReady(const base::ListValue* args) {
+ AllowJavascript();
+
+ // Send the time zone automatic detection policy in case it changed after the
+ // handler was created.
+ NotifyTimezoneAutomaticDetectionPolicy();
+}
+
+void DateTimeHandler::HandleGetTimeZones(const base::ListValue* args) {
+ AllowJavascript();
+
+ CHECK_EQ(1U, args->GetSize());
+ const base::Value* callback_id;
+ CHECK(args->Get(0, &callback_id));
+ ResolveJavascriptCallback(*callback_id, *system::GetTimezoneList().release());
+}
+
+void DateTimeHandler::HandleShowSetDateTimeUI(const base::ListValue* args) {
+ // Make sure the clock status hasn't changed since the button was clicked.
+ if (!DBusThreadManager::Get()->GetSystemClockClient()->CanSetTime())
+ return;
+ SetTimeDialog::ShowDialogInParent(
+ web_ui()->GetWebContents()->GetTopLevelNativeWindow());
+}
+
+void DateTimeHandler::NotifyTimezoneAutomaticDetectionPolicy() {
+ bool managed = !IsTimezoneAutomaticDetectionUserEditable();
+ bool force_enabled = managed &&
+ g_browser_process->platform_part()
+ ->GetTimezoneResolverManager()
+ ->ShouldApplyResolvedTimezone();
+
+ FireWebUIListener("time-zone-auto-detect-policy", base::Value(managed),
+ base::Value(force_enabled));
+}
+
+void DateTimeHandler::SystemClockCanSetTimeChanged(bool can_set_time) {
+ FireWebUIListener("can-set-date-time-changed", base::Value(can_set_time));
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.h
new file mode 100644
index 00000000000..b04142f82f7
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/date_time_handler.h
@@ -0,0 +1,78 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DATE_TIME_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DATE_TIME_HANDLER_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/scoped_observer.h"
+#include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "chromeos/dbus/system_clock_client.h"
+#include "components/prefs/pref_change_registrar.h"
+
+namespace base {
+class ListValue;
+}
+
+namespace content {
+class WebUIDataSource;
+}
+
+namespace chromeos {
+namespace settings {
+
+// Chrome OS date and time settings page UI handler.
+class DateTimeHandler : public ::settings::SettingsPageUIHandler,
+ public SystemClockClient::Observer {
+ public:
+ ~DateTimeHandler() override;
+
+ // Adds load-time values to html_source before creating the handler.
+ static DateTimeHandler* Create(content::WebUIDataSource* html_source);
+
+ // SettingsPageUIHandler implementation.
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override;
+ void OnJavascriptDisallowed() override;
+
+ private:
+ DateTimeHandler();
+
+ // SystemClockClient::Observer implementation.
+ void SystemClockCanSetTimeChanged(bool can_set_time) override;
+
+ // Called when the page is ready.
+ void HandleDateTimePageReady(const base::ListValue* args);
+
+ // Handler to fetch the list of time zones.
+ void HandleGetTimeZones(const base::ListValue* args);
+
+ // Called to show the Set Time UI.
+ void HandleShowSetDateTimeUI(const base::ListValue* args);
+
+ // Updates the UI, enabling or disabling the time zone automatic detection
+ // setting according to policy.
+ void NotifyTimezoneAutomaticDetectionPolicy();
+
+ std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
+ system_timezone_policy_subscription_;
+
+ // Used to listen to changes to the system time zone detection policy.
+ PrefChangeRegistrar local_state_pref_change_registrar_;
+
+ ScopedObserver<SystemClockClient, SystemClockClient::Observer>
+ scoped_observer_;
+ base::WeakPtrFactory<DateTimeHandler> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(DateTimeHandler);
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DATE_TIME_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
new file mode 100644
index 00000000000..dbd70059915
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
@@ -0,0 +1,82 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h"
+
+#include "ash/new_window_controller.h"
+#include "ash/shell.h"
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/values.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chromeos/chromeos_switches.h"
+#include "content/public/browser/web_ui.h"
+#include "ui/events/devices/input_device_manager.h"
+
+namespace {
+
+bool HasExternalKeyboard() {
+ for (const ui::InputDevice& keyboard :
+ ui::InputDeviceManager::GetInstance()->GetKeyboardDevices()) {
+ if (keyboard.type == ui::InputDeviceType::INPUT_DEVICE_EXTERNAL)
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace
+
+namespace chromeos {
+namespace settings {
+
+KeyboardHandler::KeyboardHandler(content::WebUI* webui)
+ : profile_(Profile::FromWebUI(webui)), observer_(this) {}
+
+KeyboardHandler::~KeyboardHandler() {
+}
+
+void KeyboardHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "initializeKeyboardSettings",
+ base::Bind(&KeyboardHandler::HandleInitialize,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "showKeyboardShortcutsOverlay",
+ base::Bind(&KeyboardHandler::HandleShowKeyboardShortcutsOverlay,
+ base::Unretained(this)));
+}
+
+void KeyboardHandler::OnJavascriptAllowed() {
+ observer_.Add(ui::InputDeviceManager::GetInstance());
+}
+
+void KeyboardHandler::OnJavascriptDisallowed() {
+ observer_.RemoveAll();
+}
+
+void KeyboardHandler::OnKeyboardDeviceConfigurationChanged() {
+ UpdateShowKeys();
+}
+
+void KeyboardHandler::HandleInitialize(const base::ListValue* args) {
+ AllowJavascript();
+ UpdateShowKeys();
+}
+
+void KeyboardHandler::HandleShowKeyboardShortcutsOverlay(
+ const base::ListValue* args) const {
+ ash::Shell::Get()->new_window_controller()->ShowKeyboardOverlay();
+}
+
+void KeyboardHandler::UpdateShowKeys() {
+ const base::Value has_caps_lock(HasExternalKeyboard());
+ const base::Value has_diamond_key(
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ chromeos::switches::kHasChromeOSDiamondKey));
+ FireWebUIListener("show-keys-changed", has_caps_lock, has_diamond_key);
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h
new file mode 100644
index 00000000000..7ac9d447d48
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h
@@ -0,0 +1,67 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_KEYBOARD_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_KEYBOARD_HANDLER_H_
+
+#include "base/macros.h"
+#include "base/scoped_observer.h"
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "ui/events/devices/input_device_event_observer.h"
+
+namespace base {
+class ListValue;
+}
+
+namespace content {
+class WebUI;
+}
+
+namespace ui {
+class InputDeviceManager;
+}
+
+class Profile;
+
+namespace chromeos {
+namespace settings {
+
+// Chrome OS "Keyboard" settings page UI handler.
+class KeyboardHandler
+ : public ::settings::SettingsPageUIHandler,
+ public ui::InputDeviceEventObserver {
+ public:
+ explicit KeyboardHandler(content::WebUI* webui);
+ ~KeyboardHandler() override;
+
+ // SettingsPageUIHandler implementation.
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override;
+ void OnJavascriptDisallowed() override;
+
+ // ui::InputDeviceEventObserver implementation.
+ void OnKeyboardDeviceConfigurationChanged() override;
+
+ private:
+ // Initializes the page with the current keyboard information.
+ void HandleInitialize(const base::ListValue* args);
+
+ // Shows the Ash keyboard shortcuts overlay.
+ void HandleShowKeyboardShortcutsOverlay(const base::ListValue* args) const;
+
+ // Shows or hides the Caps Lock and Diamond key settings based on whether the
+ // system status.
+ void UpdateShowKeys();
+
+ Profile* profile_; // Weak pointer.
+
+ ScopedObserver<ui::InputDeviceManager, KeyboardHandler> observer_;
+
+ DISALLOW_COPY_AND_ASSIGN(KeyboardHandler);
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_KEYBOARD_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.cc
new file mode 100644
index 00000000000..061dad6d182
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.cc
@@ -0,0 +1,51 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.h"
+
+#include "base/bind.h"
+#include "base/values.h"
+#include "content/public/browser/web_ui.h"
+
+namespace chromeos {
+namespace settings {
+
+PointerHandler::PointerHandler() {}
+
+PointerHandler::~PointerHandler() {}
+
+void PointerHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "initializePointerSettings",
+ base::Bind(&PointerHandler::HandleInitialize, base::Unretained(this)));
+}
+
+void PointerHandler::OnJavascriptAllowed() {
+ if (!pointer_device_observer_) {
+ pointer_device_observer_.reset(new system::PointerDeviceObserver());
+ pointer_device_observer_->Init();
+ }
+
+ pointer_device_observer_->AddObserver(this);
+ pointer_device_observer_->CheckDevices();
+}
+
+void PointerHandler::OnJavascriptDisallowed() {
+ pointer_device_observer_->RemoveObserver(this);
+}
+
+void PointerHandler::TouchpadExists(bool exists) {
+ FireWebUIListener("has-touchpad-changed", base::Value(exists));
+}
+
+void PointerHandler::MouseExists(bool exists) {
+ FireWebUIListener("has-mouse-changed", base::Value(exists));
+}
+
+void PointerHandler::HandleInitialize(const base::ListValue* args) {
+ AllowJavascript();
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.h
new file mode 100644
index 00000000000..25f54393c73
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_pointer_handler.h
@@ -0,0 +1,51 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_POINTER_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_POINTER_HANDLER_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "chrome/browser/chromeos/system/pointer_device_observer.h"
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+
+namespace base {
+class ListValue;
+}
+
+namespace chromeos {
+namespace settings {
+
+// Chrome OS "Mouse and touchpad" settings page UI handler.
+class PointerHandler
+ : public ::settings::SettingsPageUIHandler,
+ public chromeos::system::PointerDeviceObserver::Observer {
+ public:
+ PointerHandler();
+ ~PointerHandler() override;
+
+ // SettingsPageUIHandler implementation.
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override;
+ void OnJavascriptDisallowed() override;
+
+ private:
+ // PointerDeviceObserver implementation.
+ void TouchpadExists(bool exists) override;
+ void MouseExists(bool exists) override;
+
+ // Initializes the page with the current pointer information.
+ void HandleInitialize(const base::ListValue* args);
+
+ std::unique_ptr<chromeos::system::PointerDeviceObserver>
+ pointer_device_observer_;
+
+ DISALLOW_COPY_AND_ASSIGN(PointerHandler);
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_POINTER_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc
new file mode 100644
index 00000000000..535e9418eeb
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc
@@ -0,0 +1,138 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/device_power_handler.h"
+
+#include <memory>
+#include <utility>
+
+#include "ash/resources/grit/ash_resources.h"
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/grit/generated_resources.h"
+#include "content/public/browser/web_ui.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/l10n/time_format.h"
+#include "ui/base/webui/web_ui_util.h"
+
+namespace chromeos {
+namespace settings {
+namespace {
+
+base::string16 GetBatteryTimeText(base::TimeDelta time_left) {
+ int hour = 0;
+ int min = 0;
+ ash::PowerStatus::SplitTimeIntoHoursAndMinutes(time_left, &hour, &min);
+
+ base::string16 time_text;
+ if (hour == 0 || min == 0) {
+ // Display only one unit ("2 hours" or "10 minutes").
+ return ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_DURATION,
+ ui::TimeFormat::LENGTH_LONG, time_left);
+ }
+
+ return ui::TimeFormat::Detailed(ui::TimeFormat::FORMAT_DURATION,
+ ui::TimeFormat::LENGTH_LONG,
+ -1, // force hour and minute output
+ time_left);
+}
+
+} // namespace
+
+PowerHandler::PowerHandler()
+ : power_observer_(this) {
+ power_status_ = ash::PowerStatus::Get();
+}
+
+PowerHandler::~PowerHandler() {}
+
+void PowerHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "updatePowerStatus", base::Bind(&PowerHandler::HandleUpdatePowerStatus,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "setPowerSource",
+ base::Bind(&PowerHandler::HandleSetPowerSource, base::Unretained(this)));
+}
+
+void PowerHandler::OnJavascriptAllowed() {
+ power_observer_.Add(power_status_);
+}
+
+void PowerHandler::OnJavascriptDisallowed() {
+ power_observer_.RemoveAll();
+}
+
+void PowerHandler::OnPowerStatusChanged() {
+ SendBatteryStatus();
+ SendPowerSources();
+}
+
+void PowerHandler::HandleUpdatePowerStatus(const base::ListValue* args) {
+ AllowJavascript();
+ power_status_->RequestStatusUpdate();
+}
+
+void PowerHandler::HandleSetPowerSource(const base::ListValue* args) {
+ AllowJavascript();
+
+ std::string id;
+ CHECK(args->GetString(0, &id));
+ power_status_->SetPowerSource(id);
+}
+
+void PowerHandler::SendBatteryStatus() {
+ bool charging = power_status_->IsBatteryCharging();
+ bool calculating = power_status_->IsBatteryTimeBeingCalculated();
+ int percent = power_status_->GetRoundedBatteryPercent();
+ base::TimeDelta time_left;
+ bool show_time = false;
+
+ if (!calculating) {
+ time_left = charging ? power_status_->GetBatteryTimeToFull()
+ : power_status_->GetBatteryTimeToEmpty();
+ show_time = ash::PowerStatus::ShouldDisplayBatteryTime(time_left);
+ }
+
+ base::string16 status_text;
+ if (show_time) {
+ status_text = l10n_util::GetStringFUTF16(
+ charging ? IDS_OPTIONS_BATTERY_STATUS_CHARGING
+ : IDS_OPTIONS_BATTERY_STATUS,
+ base::IntToString16(percent), GetBatteryTimeText(time_left));
+ } else {
+ status_text = l10n_util::GetStringFUTF16(IDS_OPTIONS_BATTERY_STATUS_SHORT,
+ base::IntToString16(percent));
+ }
+
+ base::DictionaryValue battery_dict;
+ battery_dict.SetBoolean("charging", charging);
+ battery_dict.SetBoolean("calculating", calculating);
+ battery_dict.SetInteger("percent", percent);
+ battery_dict.SetString("statusText", status_text);
+
+ FireWebUIListener("battery-status-changed", battery_dict);
+}
+
+void PowerHandler::SendPowerSources() {
+ base::ListValue sources_list;
+ for (const auto& source : power_status_->GetPowerSources()) {
+ std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
+ dict->SetString("id", source.id);
+ dict->SetInteger("type", source.type);
+ dict->SetString("description",
+ l10n_util::GetStringUTF16(source.description_id));
+ sources_list.Append(std::move(dict));
+ }
+
+ FireWebUIListener("power-sources-changed", sources_list,
+ base::Value(power_status_->GetCurrentPowerSourceID()),
+ base::Value(power_status_->IsUsbChargerConnected()));
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h
new file mode 100644
index 00000000000..eaaf0cc9a58
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_power_handler.h
@@ -0,0 +1,59 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_POWER_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_POWER_HANDLER_H_
+
+#include "ash/system/power/power_status.h"
+#include "base/macros.h"
+#include "base/scoped_observer.h"
+#include "base/strings/string16.h"
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+
+namespace base {
+class ListValue;
+}
+
+namespace chromeos {
+namespace settings {
+
+// Chrome OS battery status and power settings handler.
+class PowerHandler : public ::settings::SettingsPageUIHandler,
+ public ash::PowerStatus::Observer {
+ public:
+ PowerHandler();
+ ~PowerHandler() override;
+
+ // SettingsPageUIHandler implementation.
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override;
+ void OnJavascriptDisallowed() override;
+
+ // ash::PowerStatus::Observer implementation.
+ void OnPowerStatusChanged() override;
+
+ private:
+ // Handler to request updating the power status.
+ void HandleUpdatePowerStatus(const base::ListValue* args);
+
+ // Handler to change the power source.
+ void HandleSetPowerSource(const base::ListValue* args);
+
+ // Updates the UI with the current battery status.
+ void SendBatteryStatus();
+
+ // Updates the UI with a list of available dual-role power sources.
+ void SendPowerSources();
+
+ ash::PowerStatus* power_status_;
+
+ ScopedObserver<ash::PowerStatus, PowerHandler> power_observer_;
+
+ DISALLOW_COPY_AND_ASSIGN(PowerHandler);
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_POWER_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc
new file mode 100644
index 00000000000..5b59c57ccdb
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.cc
@@ -0,0 +1,370 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h"
+
+#include <algorithm>
+#include <numeric>
+#include <string>
+
+#include "base/files/file_util.h"
+#include "base/sys_info.h"
+#include "base/task_scheduler/post_task.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browsing_data/browsing_data_appcache_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_cache_storage_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_channel_id_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_database_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_flash_lso_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
+#include "chrome/browser/browsing_data/browsing_data_service_worker_helper.h"
+#include "chrome/browser/chromeos/arc/arc_util.h"
+#include "chrome/browser/chromeos/drive/file_system_util.h"
+#include "chrome/browser/chromeos/file_manager/path_util.h"
+#include "chrome/browser/platform_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/grit/generated_resources.h"
+#include "chromeos/cryptohome/homedir_methods.h"
+#include "components/arc/arc_util.h"
+#include "components/browsing_data/content/conditional_cache_counting_helper.h"
+#include "components/drive/chromeos/file_system_interface.h"
+#include "components/user_manager/user_manager.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/storage_partition.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/text/bytes_formatting.h"
+
+namespace chromeos {
+namespace settings {
+namespace {
+
+void GetSizeStatBlocking(const base::FilePath& mount_path,
+ int64_t* total_size,
+ int64_t* available_size) {
+ int64_t size = base::SysInfo::AmountOfTotalDiskSpace(mount_path);
+ if (size >= 0)
+ *total_size = size;
+ size = base::SysInfo::AmountOfFreeDiskSpace(mount_path);
+ if (size >= 0)
+ *available_size = size;
+}
+
+// Threshold to show a message indicating space is critically low (512 MB).
+const int64_t kSpaceCriticallyLowBytes = 512 * 1024 * 1024;
+
+// Threshold to show a message indicating space is low (1 GB).
+const int64_t kSpaceLowBytes = 1 * 1024 * 1024 * 1024;
+
+} // namespace
+
+StorageHandler::StorageHandler()
+ : browser_cache_size_(-1),
+ has_browser_cache_size_(false),
+ browser_site_data_size_(-1),
+ has_browser_site_data_size_(false),
+ updating_downloads_size_(false),
+ updating_drive_cache_size_(false),
+ updating_browsing_data_size_(false),
+ updating_android_size_(false),
+ updating_other_users_size_(false),
+ weak_ptr_factory_(this) {}
+
+StorageHandler::~StorageHandler() {
+}
+
+void StorageHandler::RegisterMessages() {
+ DCHECK(web_ui());
+
+ web_ui()->RegisterMessageCallback(
+ "updateStorageInfo",
+ base::Bind(&StorageHandler::HandleUpdateStorageInfo,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "openDownloads",
+ base::Bind(&StorageHandler::HandleOpenDownloads,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "openArcStorage",
+ base::Bind(&StorageHandler::HandleOpenArcStorage,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "clearDriveCache",
+ base::Bind(&StorageHandler::HandleClearDriveCache,
+ base::Unretained(this)));
+}
+
+void StorageHandler::HandleUpdateStorageInfo(const base::ListValue* args) {
+ AllowJavascript();
+
+ UpdateSizeStat();
+ UpdateDownloadsSize();
+ UpdateDriveCacheSize();
+ UpdateBrowsingDataSize();
+ UpdateOtherUsersSize();
+ UpdateAndroidSize();
+}
+
+void StorageHandler::HandleOpenDownloads(
+ const base::ListValue* unused_args) {
+ Profile* const profile = Profile::FromWebUI(web_ui());
+ const base::FilePath downloads_path =
+ file_manager::util::GetDownloadsFolderForProfile(profile);
+ platform_util::OpenItem(
+ profile,
+ downloads_path,
+ platform_util::OPEN_FOLDER,
+ platform_util::OpenOperationCallback());
+}
+
+void StorageHandler::HandleOpenArcStorage(
+ const base::ListValue* unused_args) {
+ arc::ArcStorageManager::Get()->OpenPrivateVolumeSettings();
+}
+
+void StorageHandler::HandleClearDriveCache(
+ const base::ListValue* unused_args) {
+ drive::FileSystemInterface* const file_system =
+ drive::util::GetFileSystemByProfile(Profile::FromWebUI(web_ui()));
+ file_system->FreeDiskSpaceIfNeededFor(
+ std::numeric_limits<int64_t>::max(), // Removes as much as possible.
+ base::Bind(&StorageHandler::OnClearDriveCacheDone,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void StorageHandler::UpdateSizeStat() {
+ Profile* const profile = Profile::FromWebUI(web_ui());
+ const base::FilePath downloads_path =
+ file_manager::util::GetDownloadsFolderForProfile(profile);
+
+ int64_t* total_size = new int64_t(0);
+ int64_t* available_size = new int64_t(0);
+ base::PostTaskWithTraitsAndReply(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
+ base::Bind(&GetSizeStatBlocking, downloads_path, total_size,
+ available_size),
+ base::Bind(&StorageHandler::OnGetSizeStat, weak_ptr_factory_.GetWeakPtr(),
+ base::Owned(total_size), base::Owned(available_size)));
+}
+
+void StorageHandler::OnGetSizeStat(int64_t* total_size,
+ int64_t* available_size) {
+ int64_t used_size = *total_size - *available_size;
+ base::DictionaryValue size_stat;
+ size_stat.SetString("totalSize", ui::FormatBytes(*total_size));
+ size_stat.SetString("availableSize", ui::FormatBytes(*available_size));
+ size_stat.SetString("usedSize", ui::FormatBytes(used_size));
+ size_stat.SetDouble("usedRatio",
+ static_cast<double>(used_size) / *total_size);
+ int storage_space_state = STORAGE_SPACE_NORMAL;
+ if (*available_size < kSpaceCriticallyLowBytes)
+ storage_space_state = STORAGE_SPACE_CRITICALLY_LOW;
+ else if (*available_size < kSpaceLowBytes)
+ storage_space_state = STORAGE_SPACE_LOW;
+ size_stat.SetInteger("spaceState", storage_space_state);
+
+ FireWebUIListener("storage-size-stat-changed", size_stat);
+}
+
+void StorageHandler::UpdateDownloadsSize() {
+ if (updating_downloads_size_)
+ return;
+ updating_downloads_size_ = true;
+
+ Profile* const profile = Profile::FromWebUI(web_ui());
+ const base::FilePath downloads_path =
+ file_manager::util::GetDownloadsFolderForProfile(profile);
+
+ base::PostTaskWithTraitsAndReplyWithResult(
+ FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
+ base::Bind(&base::ComputeDirectorySize, downloads_path),
+ base::Bind(&StorageHandler::OnGetDownloadsSize,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void StorageHandler::OnGetDownloadsSize(int64_t size) {
+ updating_downloads_size_ = false;
+ FireWebUIListener("storage-downloads-size-changed",
+ base::Value(ui::FormatBytes(size)));
+}
+
+void StorageHandler::UpdateDriveCacheSize() {
+ if (updating_drive_cache_size_)
+ return;
+
+ drive::FileSystemInterface* const file_system =
+ drive::util::GetFileSystemByProfile(Profile::FromWebUI(web_ui()));
+ if (!file_system)
+ return;
+
+ // Shows the item "Offline cache" and start calculating size.
+ FireWebUIListener("storage-drive-enabled-changed", base::Value(true));
+ updating_drive_cache_size_ = true;
+ file_system->CalculateCacheSize(base::Bind(
+ &StorageHandler::OnGetDriveCacheSize, weak_ptr_factory_.GetWeakPtr()));
+}
+
+void StorageHandler::OnGetDriveCacheSize(int64_t size) {
+ updating_drive_cache_size_ = false;
+ FireWebUIListener("storage-drive-cache-size-changed",
+ base::Value(ui::FormatBytes(size)), base::Value(size > 0));
+}
+
+void StorageHandler::UpdateBrowsingDataSize() {
+ if (updating_browsing_data_size_)
+ return;
+ updating_browsing_data_size_ = true;
+
+ has_browser_cache_size_ = false;
+ has_browser_site_data_size_ = false;
+ Profile* const profile = Profile::FromWebUI(web_ui());
+ // Fetch the size of http cache in browsing data.
+ // ConditionalCacheCountingHelper deletes itself when it is done.
+ browsing_data::ConditionalCacheCountingHelper::CreateForRange(
+ content::BrowserContext::GetDefaultStoragePartition(profile),
+ base::Time(), base::Time::Max())
+ ->CountAndDestroySelfWhenFinished(base::Bind(
+ &StorageHandler::OnGetCacheSize, weak_ptr_factory_.GetWeakPtr()));
+
+ // Fetch the size of site data in browsing data.
+ if (!site_data_size_collector_.get()) {
+ content::StoragePartition* storage_partition =
+ content::BrowserContext::GetDefaultStoragePartition(profile);
+ site_data_size_collector_.reset(new SiteDataSizeCollector(
+ storage_partition->GetPath(),
+ new BrowsingDataCookieHelper(profile->GetRequestContext()),
+ new BrowsingDataDatabaseHelper(profile),
+ new BrowsingDataLocalStorageHelper(profile),
+ new BrowsingDataAppCacheHelper(profile),
+ new BrowsingDataIndexedDBHelper(
+ storage_partition->GetIndexedDBContext()),
+ BrowsingDataFileSystemHelper::Create(
+ storage_partition->GetFileSystemContext()),
+ BrowsingDataChannelIDHelper::Create(profile->GetRequestContext()),
+ new BrowsingDataServiceWorkerHelper(
+ storage_partition->GetServiceWorkerContext()),
+ new BrowsingDataCacheStorageHelper(
+ storage_partition->GetCacheStorageContext()),
+ BrowsingDataFlashLSOHelper::Create(profile)));
+ }
+ site_data_size_collector_->Fetch(
+ base::Bind(&StorageHandler::OnGetBrowsingDataSize,
+ weak_ptr_factory_.GetWeakPtr(), true));
+}
+
+void StorageHandler::OnGetCacheSize(bool is_upper_limit, int64_t size) {
+ DCHECK(!is_upper_limit);
+ OnGetBrowsingDataSize(false, size);
+}
+
+void StorageHandler::OnGetBrowsingDataSize(bool is_site_data, int64_t size) {
+ if (is_site_data) {
+ has_browser_site_data_size_ = true;
+ browser_site_data_size_ = size;
+ } else {
+ has_browser_cache_size_ = true;
+ browser_cache_size_ = size;
+ }
+ if (has_browser_cache_size_ && has_browser_site_data_size_) {
+ base::string16 size_string;
+ if (browser_cache_size_ >= 0 && browser_site_data_size_ >= 0) {
+ size_string = ui::FormatBytes(
+ browser_site_data_size_ + browser_cache_size_);
+ } else {
+ size_string = l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_STORAGE_SIZE_UNKNOWN);
+ }
+ updating_browsing_data_size_ = false;
+ FireWebUIListener("storage-browsing-data-size-changed",
+ base::Value(size_string));
+ }
+}
+
+void StorageHandler::UpdateOtherUsersSize() {
+ if (updating_other_users_size_)
+ return;
+ updating_other_users_size_ = true;
+
+ other_users_.clear();
+ user_sizes_.clear();
+ const user_manager::UserList& users =
+ user_manager::UserManager::Get()->GetUsers();
+ for (auto* user : users) {
+ if (user->is_active())
+ continue;
+ other_users_.push_back(user);
+ cryptohome::HomedirMethods::GetInstance()->GetAccountDiskUsage(
+ cryptohome::Identification(user->GetAccountId()),
+ base::Bind(&StorageHandler::OnGetOtherUserSize,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+ // We should show "0 B" if there is no other user.
+ if (other_users_.empty()) {
+ updating_other_users_size_ = false;
+ FireWebUIListener("storage-other-users-size-changed",
+ base::Value(ui::FormatBytes(0)));
+ }
+}
+
+void StorageHandler::OnGetOtherUserSize(bool success, int64_t size) {
+ user_sizes_.push_back(success ? size : -1);
+ if (user_sizes_.size() == other_users_.size()) {
+ base::string16 size_string;
+ // If all the requests succeed, shows the total bytes in the UI.
+ if (std::count(user_sizes_.begin(), user_sizes_.end(), -1) == 0) {
+ size_string = ui::FormatBytes(
+ std::accumulate(user_sizes_.begin(), user_sizes_.end(), 0LL));
+ } else {
+ size_string = l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_STORAGE_SIZE_UNKNOWN);
+ }
+ updating_other_users_size_ = false;
+ FireWebUIListener("storage-other-users-size-changed",
+ base::Value(size_string));
+ }
+}
+
+void StorageHandler::UpdateAndroidSize() {
+ if (updating_android_size_)
+ return;
+ updating_android_size_ = true;
+
+ Profile* const profile = Profile::FromWebUI(web_ui());
+ if (!arc::IsArcPlayStoreEnabledForProfile(profile) ||
+ arc::IsArcOptInVerificationDisabled()) {
+ return;
+ }
+
+ // Shows the item "Android apps and cache" and start calculating size.
+ FireWebUIListener("storage-android-enabled-changed", base::Value(true));
+ bool success = arc::ArcStorageManager::Get()->GetApplicationsSize(base::Bind(
+ &StorageHandler::OnGetAndroidSize, weak_ptr_factory_.GetWeakPtr()));
+ if (!success)
+ updating_android_size_ = false;
+}
+
+void StorageHandler::OnGetAndroidSize(bool succeeded,
+ arc::mojom::ApplicationsSizePtr size) {
+ base::string16 size_string;
+ if (succeeded) {
+ uint64_t total_bytes = size->total_code_bytes +
+ size->total_data_bytes +
+ size->total_cache_bytes;
+ size_string = ui::FormatBytes(total_bytes);
+ } else {
+ size_string = l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_STORAGE_SIZE_UNKNOWN);
+ }
+ updating_android_size_ = false;
+ FireWebUIListener("storage-android-size-changed", base::Value(size_string));
+}
+
+void StorageHandler::OnClearDriveCacheDone(bool success) {
+ UpdateDriveCacheSize();
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h
new file mode 100644
index 00000000000..9da1d5d437b
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_storage_handler.h
@@ -0,0 +1,127 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_STORAGE_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_STORAGE_HANDLER_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/browsing_data/site_data_size_collector.h"
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "components/arc/storage_manager/arc_storage_manager.h"
+#include "components/user_manager/user.h"
+
+namespace chromeos {
+namespace settings {
+
+class StorageHandler : public ::settings::SettingsPageUIHandler {
+ public:
+ // Enumeration for device state about remaining space. These values must be
+ // kept in sync with settings.StorageSpaceState in JS code.
+ enum StorageSpaceState {
+ STORAGE_SPACE_NORMAL = 0,
+ STORAGE_SPACE_LOW = 1,
+ STORAGE_SPACE_CRITICALLY_LOW = 2,
+ };
+
+ StorageHandler();
+ ~StorageHandler() override;
+
+ // SettingsPageUIHandler implementation.
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override {}
+ void OnJavascriptDisallowed() override {}
+
+ private:
+ // Handlers of JS messages.
+ void HandleUpdateStorageInfo(const base::ListValue* unused_args);
+ void HandleOpenDownloads(const base::ListValue* unused_args);
+ void HandleOpenArcStorage(const base::ListValue* unused_args);
+ void HandleClearDriveCache(const base::ListValue* unused_args);
+
+ // Requests updating disk space information.
+ void UpdateSizeStat();
+
+ // Callback to update the UI about disk space information.
+ void OnGetSizeStat(int64_t* total_size, int64_t* available_size);
+
+ // Requests updating the size of Downloads directory.
+ void UpdateDownloadsSize();
+
+ // Callback to update the UI about the size of Downloads directory.
+ void OnGetDownloadsSize(int64_t size);
+
+ // Requests updating the size of Drive Cache.
+ void UpdateDriveCacheSize();
+
+ // Callback to update the UI about the size of Drive Cache.
+ void OnGetDriveCacheSize(int64_t size);
+
+ // Requests updating the size of browsing data.
+ void UpdateBrowsingDataSize();
+
+ // Callback to receive the cache size.
+ void OnGetCacheSize(bool is_upper_limit, int64_t size);
+
+ // Callback to update the UI about the size of browsing data.
+ void OnGetBrowsingDataSize(bool is_site_data, int64_t size);
+
+ // Requests updating the total size of other users' data.
+ void UpdateOtherUsersSize();
+
+ // Callback to save the fetched user sizes and update the UI.
+ void OnGetOtherUserSize(bool success, int64_t size);
+
+ // Requests updating the space size used by Android apps and cache.
+ void UpdateAndroidSize();
+
+ // Callback to update the UI about Android apps and cache.
+ void OnGetAndroidSize(bool succeeded, arc::mojom::ApplicationsSizePtr size);
+
+ // Callback called when clearing Drive cache is done.
+ void OnClearDriveCacheDone(bool success);
+
+ // Total size of cache data in browsing data.
+ int64_t browser_cache_size_;
+
+ // True if we have already received the size of http cache.
+ bool has_browser_cache_size_;
+
+ // Total size of site data in browsing data.
+ int64_t browser_site_data_size_;
+
+ // True if we have already received the size of site data.
+ bool has_browser_site_data_size_;
+
+ // The list of other users whose directory sizes will be accumulated as the
+ // size of "Other users".
+ user_manager::UserList other_users_;
+
+ // Fetched sizes of user directories.
+ std::vector<int64_t> user_sizes_;
+
+ // Helper to compute the total size of all types of site date.
+ std::unique_ptr<SiteDataSizeCollector> site_data_size_collector_;
+
+ // Flags indicating fetch operations for storage sizes are ongoing.
+ bool updating_downloads_size_;
+ bool updating_drive_cache_size_;
+ bool updating_browsing_data_size_;
+ bool updating_android_size_;
+ bool updating_other_users_size_;
+
+ base::WeakPtrFactory<StorageHandler> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(StorageHandler);
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_STORAGE_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc
new file mode 100644
index 00000000000..7f7ba9c3b47
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.cc
@@ -0,0 +1,143 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.h"
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "ash/system/palette/palette_utils.h"
+#include "base/bind.h"
+#include "chrome/browser/chromeos/arc/arc_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
+#include "ui/events/devices/input_device_manager.h"
+
+namespace chromeos {
+namespace settings {
+
+namespace {
+
+// Keys in objects passed to onNoteTakingAppsUpdated.
+constexpr char kAppNameKey[] = "name";
+constexpr char kAppIdKey[] = "value";
+constexpr char kAppPreferredKey[] = "preferred";
+constexpr char kAppLockScreenSupportKey[] = "supportsLockScreen";
+
+} // namespace
+
+StylusHandler::StylusHandler() {
+ NoteTakingHelper::Get()->AddObserver(this);
+ ui::InputDeviceManager::GetInstance()->AddObserver(this);
+}
+
+StylusHandler::~StylusHandler() {
+ ui::InputDeviceManager::GetInstance()->RemoveObserver(this);
+ NoteTakingHelper::Get()->RemoveObserver(this);
+}
+
+void StylusHandler::RegisterMessages() {
+ DCHECK(web_ui());
+
+ web_ui()->RegisterMessageCallback(
+ "initializeStylusSettings",
+ base::Bind(&StylusHandler::HandleInitialize, base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "requestNoteTakingApps",
+ base::Bind(&StylusHandler::RequestApps, base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "setPreferredNoteTakingApp",
+ base::Bind(&StylusHandler::SetPreferredNoteTakingApp,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "showPlayStoreApps",
+ base::Bind(&StylusHandler::ShowPlayStoreApps, base::Unretained(this)));
+}
+
+void StylusHandler::OnAvailableNoteTakingAppsUpdated() {
+ UpdateNoteTakingApps();
+}
+
+void StylusHandler::OnDeviceListsComplete() {
+ SendHasStylus();
+}
+
+void StylusHandler::UpdateNoteTakingApps() {
+ bool waiting_for_android = false;
+ note_taking_app_ids_.clear();
+ base::ListValue apps_list;
+
+ NoteTakingHelper* helper = NoteTakingHelper::Get();
+ if (helper->play_store_enabled() && !helper->android_apps_received()) {
+ // If Play Store is enabled but not ready yet, let the JS know so it can
+ // disable the menu and display an explanatory message.
+ waiting_for_android = true;
+ } else {
+ std::vector<NoteTakingAppInfo> available_apps =
+ helper->GetAvailableApps(Profile::FromWebUI(web_ui()));
+ for (const NoteTakingAppInfo& info : available_apps) {
+ auto dict = base::MakeUnique<base::DictionaryValue>();
+ dict->SetString(kAppNameKey, info.name);
+ dict->SetString(kAppIdKey, info.app_id);
+ dict->SetBoolean(kAppPreferredKey, info.preferred);
+ dict->SetBoolean(kAppLockScreenSupportKey,
+ info.lock_screen_support !=
+ NoteTakingLockScreenSupport::kNotSupported);
+ apps_list.Append(std::move(dict));
+
+ note_taking_app_ids_.insert(info.app_id);
+ }
+ }
+
+ AllowJavascript();
+ FireWebUIListener("onNoteTakingAppsUpdated", apps_list,
+ base::Value(waiting_for_android));
+}
+
+void StylusHandler::RequestApps(const base::ListValue* unused_args) {
+ UpdateNoteTakingApps();
+}
+
+void StylusHandler::SetPreferredNoteTakingApp(const base::ListValue* args) {
+ std::string app_id;
+ CHECK(args->GetString(0, &app_id));
+
+ // Sanity check: make sure that the ID we got back from WebUI is in the
+ // currently-available set.
+ if (!note_taking_app_ids_.count(app_id)) {
+ LOG(ERROR) << "Got unknown note-taking-app ID \"" << app_id << "\"";
+ return;
+ }
+
+ NoteTakingHelper::Get()->SetPreferredApp(Profile::FromWebUI(web_ui()),
+ app_id);
+}
+
+void StylusHandler::HandleInitialize(const base::ListValue* args) {
+ if (ui::InputDeviceManager::GetInstance()->AreDeviceListsComplete())
+ SendHasStylus();
+}
+
+void StylusHandler::SendHasStylus() {
+ DCHECK(ui::InputDeviceManager::GetInstance()->AreDeviceListsComplete());
+ AllowJavascript();
+ FireWebUIListener("has-stylus-changed",
+ base::Value(ash::palette_utils::HasStylusInput()));
+}
+
+void StylusHandler::ShowPlayStoreApps(const base::ListValue* args) {
+ std::string apps_url;
+ args->GetString(0, &apps_url);
+ Profile* profile = Profile::FromWebUI(web_ui());
+ if (!arc::IsArcAllowedForProfile(profile)) {
+ VLOG(1) << "ARC is not enabled for this profile";
+ return;
+ }
+
+ arc::LaunchPlayStoreWithUrl(apps_url);
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.h
new file mode 100644
index 00000000000..b8cd2567f99
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/device_stylus_handler.h
@@ -0,0 +1,63 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_STYLUS_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_STYLUS_HANDLER_H_
+
+#include <set>
+
+#include "base/macros.h"
+#include "chrome/browser/chromeos/note_taking_helper.h"
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "ui/events/devices/input_device_event_observer.h"
+
+namespace base {
+class ListValue;
+}
+
+namespace chromeos {
+namespace settings {
+
+// Chrome OS stylus settings handler.
+class StylusHandler : public ::settings::SettingsPageUIHandler,
+ public chromeos::NoteTakingHelper::Observer,
+ public ui::InputDeviceEventObserver {
+ public:
+ StylusHandler();
+ ~StylusHandler() override;
+
+ // SettingsPageUIHandler implementation.
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override {}
+ void OnJavascriptDisallowed() override {}
+
+ // chromeos::NoteTakingHelper::Observer implementation.
+ void OnAvailableNoteTakingAppsUpdated() override;
+
+ // ui::InputDeviceObserver:
+ void OnDeviceListsComplete() override;
+
+ private:
+ void UpdateNoteTakingApps();
+ void RequestApps(const base::ListValue* unused_args);
+ void SetPreferredNoteTakingApp(const base::ListValue* args);
+
+ // Called by JS to request a |SendHasStylus| call.
+ void HandleInitialize(const base::ListValue* args);
+ // Enables or disables the stylus UI section.
+ void SendHasStylus();
+
+ // Called by JS to show the Play Store Android app.
+ void ShowPlayStoreApps(const base::ListValue* args);
+
+ // IDs of available note-taking apps.
+ std::set<std::string> note_taking_app_ids_;
+
+ DISALLOW_COPY_AND_ASSIGN(StylusHandler);
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_DEVICE_STYLUS_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.cc
new file mode 100644
index 00000000000..299d20bd1b7
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.cc
@@ -0,0 +1,160 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.h"
+
+#include <string>
+
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/macros.h"
+#include "base/values.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/easy_unlock_service.h"
+#include "chrome/common/pref_names.h"
+#include "components/proximity_auth/switches.h"
+#include "content/public/browser/web_ui.h"
+#include "content/public/browser/web_ui_data_source.h"
+
+namespace chromeos {
+namespace settings {
+
+EasyUnlockSettingsHandler::EasyUnlockSettingsHandler(Profile* profile)
+ : profile_(profile) {
+ profile_pref_registrar_.Init(profile->GetPrefs());
+}
+
+EasyUnlockSettingsHandler::~EasyUnlockSettingsHandler() {
+ EasyUnlockService::Get(profile_)->RemoveObserver(this);
+}
+
+EasyUnlockSettingsHandler* EasyUnlockSettingsHandler::Create(
+ content::WebUIDataSource* html_source,
+ Profile* profile) {
+ EasyUnlockService* easy_unlock_service = EasyUnlockService::Get(profile);
+ bool allowed = easy_unlock_service->IsAllowed();
+ html_source->AddBoolean("easyUnlockAllowed", allowed);
+ html_source->AddBoolean("easyUnlockEnabled",
+ allowed ? easy_unlock_service->IsEnabled() : false);
+ if (!allowed)
+ return nullptr;
+
+ html_source->AddBoolean(
+ "easyUnlockProximityDetectionAllowed",
+ base::CommandLine::ForCurrentProcess()->HasSwitch(
+ proximity_auth::switches::kEnableProximityDetection));
+
+ return new EasyUnlockSettingsHandler(profile);
+}
+
+void EasyUnlockSettingsHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "easyUnlockGetEnabledStatus",
+ base::Bind(&EasyUnlockSettingsHandler::HandleGetEnabledStatus,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "easyUnlockStartTurnOnFlow",
+ base::Bind(&EasyUnlockSettingsHandler::HandleStartTurnOnFlow,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "easyUnlockGetTurnOffFlowStatus",
+ base::Bind(&EasyUnlockSettingsHandler::HandleGetTurnOffFlowStatus,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "easyUnlockStartTurnOffFlow",
+ base::Bind(&EasyUnlockSettingsHandler::HandleStartTurnOffFlow,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "easyUnlockCancelTurnOffFlow",
+ base::Bind(&EasyUnlockSettingsHandler::HandleCancelTurnOffFlow,
+ base::Unretained(this)));
+}
+
+void EasyUnlockSettingsHandler::OnJavascriptAllowed() {
+ EasyUnlockService::Get(profile_)->AddObserver(this);
+
+ profile_pref_registrar_.Add(
+ prefs::kEasyUnlockPairing,
+ base::Bind(&EasyUnlockSettingsHandler::SendEnabledStatus,
+ base::Unretained(this)));
+}
+
+void EasyUnlockSettingsHandler::OnJavascriptDisallowed() {
+ EasyUnlockService::Get(profile_)->RemoveObserver(this);
+ profile_pref_registrar_.RemoveAll();
+}
+
+void EasyUnlockSettingsHandler::OnTurnOffOperationStatusChanged() {
+ FireWebUIListener("easy-unlock-turn-off-flow-status",
+ base::Value(GetTurnOffFlowStatus()));
+}
+
+void EasyUnlockSettingsHandler::SendEnabledStatus() {
+ CallJavascriptFunction(
+ "cr.webUIListenerCallback", base::Value("easy-unlock-enabled-status"),
+ base::Value(EasyUnlockService::Get(profile_)->IsEnabled()));
+}
+
+std::string EasyUnlockSettingsHandler::GetTurnOffFlowStatus() {
+ EasyUnlockService::TurnOffFlowStatus status =
+ EasyUnlockService::Get(profile_)->GetTurnOffFlowStatus();
+
+ // Translate status into JS UI state string. Note the translated string
+ // should match UIState defined in easy_unlock_turn_off_dialog.js.
+ std::string status_string;
+ switch (status) {
+ case EasyUnlockService::IDLE:
+ status_string = "idle";
+ break;
+ case EasyUnlockService::PENDING:
+ status_string = "pending";
+ break;
+ case EasyUnlockService::FAIL:
+ status_string = "server-error";
+ break;
+ default:
+ LOG(ERROR) << "Unknown Easy unlock turn-off operation status: " << status;
+ status_string = "idle";
+ break;
+ }
+
+ return status_string;
+}
+
+void EasyUnlockSettingsHandler::HandleGetEnabledStatus(
+ const base::ListValue* args) {
+ AllowJavascript();
+
+ CHECK_EQ(1U, args->GetSize());
+ const base::Value* callback_id;
+ CHECK(args->Get(0, &callback_id));
+ ResolveJavascriptCallback(
+ *callback_id, base::Value(EasyUnlockService::Get(profile_)->IsEnabled()));
+}
+
+void EasyUnlockSettingsHandler::HandleStartTurnOnFlow(
+ const base::ListValue* args) {
+ EasyUnlockService::Get(profile_)->LaunchSetup();
+}
+
+void EasyUnlockSettingsHandler::HandleGetTurnOffFlowStatus(
+ const base::ListValue* args) {
+ CHECK_EQ(1U, args->GetSize());
+ const base::Value* callback_id;
+ CHECK(args->Get(0, &callback_id));
+ ResolveJavascriptCallback(*callback_id, base::Value(GetTurnOffFlowStatus()));
+}
+
+void EasyUnlockSettingsHandler::HandleStartTurnOffFlow(
+ const base::ListValue* args) {
+ EasyUnlockService::Get(profile_)->RunTurnOffFlow();
+}
+
+void EasyUnlockSettingsHandler::HandleCancelTurnOffFlow(
+ const base::ListValue* args) {
+ EasyUnlockService::Get(profile_)->ResetTurnOffFlow();
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.h
new file mode 100644
index 00000000000..3fb3706c524
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.h
@@ -0,0 +1,67 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_EASY_UNLOCK_SETTINGS_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_EASY_UNLOCK_SETTINGS_HANDLER_H_
+
+#include "base/macros.h"
+#include "chrome/browser/signin/easy_unlock_service_observer.h"
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "components/prefs/pref_change_registrar.h"
+
+namespace content {
+class WebUIDataSource;
+}
+
+class Profile;
+
+namespace chromeos {
+namespace settings {
+
+class EasyUnlockSettingsHandler : public ::settings::SettingsPageUIHandler,
+ public EasyUnlockServiceObserver {
+ public:
+ // Returns nullptr if EasyUnlock is not allowed for this device.
+ static EasyUnlockSettingsHandler* Create(
+ content::WebUIDataSource* html_source,
+ Profile* profile);
+
+ ~EasyUnlockSettingsHandler() override;
+
+ // SettingsPageUIHandler:
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override;
+ void OnJavascriptDisallowed() override;
+
+ // EasyUnlockServiceObserver:
+ void OnTurnOffOperationStatusChanged() override;
+
+ protected:
+ explicit EasyUnlockSettingsHandler(Profile* profile);
+
+ private:
+ FRIEND_TEST_ALL_PREFIXES(EasyUnlockSettingsHandlerTest, EnabledStatus);
+ FRIEND_TEST_ALL_PREFIXES(EasyUnlockSettingsHandlerTest, TurnOffFlowStatus);
+
+ void SendEnabledStatus();
+ std::string GetTurnOffFlowStatus();
+
+ // JS callbacks.
+ void HandleGetEnabledStatus(const base::ListValue* args);
+ void HandleStartTurnOnFlow(const base::ListValue* args);
+ void HandleGetTurnOffFlowStatus(const base::ListValue* args);
+ void HandleStartTurnOffFlow(const base::ListValue* args);
+ void HandleCancelTurnOffFlow(const base::ListValue* args);
+
+ Profile* const profile_;
+
+ PrefChangeRegistrar profile_pref_registrar_;
+
+ DISALLOW_COPY_AND_ASSIGN(EasyUnlockSettingsHandler);
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_EASY_UNLOCK_SETTINGS_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler_unittest.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler_unittest.cc
new file mode 100644
index 00000000000..d56e735aa3e
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler_unittest.cc
@@ -0,0 +1,264 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.h"
+
+#include <memory>
+
+#include "base/memory/ptr_util.h"
+#include "chrome/browser/signin/easy_unlock_service.h"
+#include "chrome/browser/signin/easy_unlock_service_factory.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/browser/web_ui_data_source.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "content/public/test/test_web_ui.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+namespace settings {
+
+namespace {
+
+class FakeEasyUnlockService : public EasyUnlockService {
+ public:
+ explicit FakeEasyUnlockService(Profile* profile)
+ : EasyUnlockService(profile),
+ turn_off_status_(IDLE),
+ is_allowed_(true),
+ is_enabled_(false) {}
+
+ TurnOffFlowStatus GetTurnOffFlowStatus() const override {
+ return turn_off_status_;
+ }
+
+ bool IsAllowed() const override { return is_allowed_; }
+ void set_is_allowed(bool is_allowed) { is_allowed_ = is_allowed; }
+
+ bool IsEnabled() const override { return is_enabled_; }
+ void set_is_enabled(bool is_enabled) { is_enabled_ = is_enabled; }
+
+ void RunTurnOffFlow() override {
+ turn_off_status_ = PENDING;
+ NotifyTurnOffOperationStatusChanged();
+ }
+
+ void ResetTurnOffFlow() override {
+ turn_off_status_ = IDLE;
+ NotifyTurnOffOperationStatusChanged();
+ }
+
+ void SetTurnOffFlowFailForTest() {
+ turn_off_status_ = FAIL;
+ NotifyTurnOffOperationStatusChanged();
+ }
+
+ private:
+ Type GetType() const override { return TYPE_REGULAR; }
+ AccountId GetAccountId() const override { return EmptyAccountId(); }
+ void LaunchSetup() override {}
+ const base::DictionaryValue* GetPermitAccess() const override {
+ return nullptr;
+ }
+ void SetPermitAccess(const base::DictionaryValue& permit) override {}
+ void ClearPermitAccess() override {}
+
+ const base::ListValue* GetRemoteDevices() const override { return nullptr; }
+ void SetRemoteDevices(const base::ListValue& devices) override {}
+ void SetRemoteBleDevices(const base::ListValue& devices) override {}
+
+ std::string GetChallenge() const override { return std::string(); }
+ std::string GetWrappedSecret() const override { return std::string(); }
+ void RecordEasySignInOutcome(const AccountId& account_id,
+ bool success) const override {}
+ void RecordPasswordLoginEvent(const AccountId& account_id) const override {}
+ void StartAutoPairing(const AutoPairingResultCallback& callback) override {}
+ void SetAutoPairingResult(bool success, const std::string& error) override {}
+
+ void InitializeInternal() override {}
+ void ShutdownInternal() override {}
+ bool IsAllowedInternal() const override { return false; }
+ void OnWillFinalizeUnlock(bool success) override {}
+ void OnSuspendDoneInternal() override {}
+
+ TurnOffFlowStatus turn_off_status_;
+ bool is_allowed_;
+ bool is_enabled_;
+};
+
+class TestEasyUnlockSettingsHandler : public EasyUnlockSettingsHandler {
+ public:
+ explicit TestEasyUnlockSettingsHandler(Profile* profile)
+ : EasyUnlockSettingsHandler(profile) {}
+
+ using EasyUnlockSettingsHandler::set_web_ui;
+};
+
+std::unique_ptr<KeyedService> CreateEasyUnlockServiceForTest(
+ content::BrowserContext* context) {
+ return base::MakeUnique<FakeEasyUnlockService>(
+ Profile::FromBrowserContext(context));
+}
+
+} // namespace
+
+class EasyUnlockSettingsHandlerTest : public testing::Test {
+ public:
+ EasyUnlockSettingsHandlerTest() {}
+
+ void SetUp() override {
+ TestingProfile::Builder builder;
+ builder.AddTestingFactory(EasyUnlockServiceFactory::GetInstance(),
+ &CreateEasyUnlockServiceForTest);
+ profile_ = builder.Build();
+ }
+
+ Profile* profile() { return profile_.get(); }
+ content::TestWebUI* web_ui() { return &web_ui_; }
+ FakeEasyUnlockService* fake_easy_unlock_service() {
+ return static_cast<FakeEasyUnlockService*>(
+ EasyUnlockService::Get(profile_.get()));
+ }
+
+ void VerifyEnabledStatusCallback(size_t expected_total_calls,
+ bool expected_status) {
+ std::string event;
+ bool status;
+
+ EXPECT_EQ(expected_total_calls, web_ui_.call_data().size());
+
+ const content::TestWebUI::CallData& data = *web_ui_.call_data().back();
+ EXPECT_EQ("cr.webUIListenerCallback", data.function_name());
+ ASSERT_TRUE(data.arg1()->GetAsString(&event));
+ EXPECT_EQ("easy-unlock-enabled-status", event);
+ ASSERT_TRUE(data.arg2()->GetAsBoolean(&status));
+
+ EXPECT_EQ(expected_status, status);
+ }
+
+ void VerifyTurnOffFlowStatusWebUIListenerCallback(
+ size_t expected_total_calls,
+ const std::string& expected_status) {
+ std::string event;
+ std::string status;
+
+ EXPECT_EQ(expected_total_calls, web_ui_.call_data().size());
+
+ const content::TestWebUI::CallData& data = *web_ui_.call_data().back();
+ EXPECT_EQ("cr.webUIListenerCallback", data.function_name());
+ ASSERT_TRUE(data.arg1()->GetAsString(&event));
+ EXPECT_EQ("easy-unlock-turn-off-flow-status", event);
+ ASSERT_TRUE(data.arg2()->GetAsString(&status));
+
+ EXPECT_EQ(expected_status, status);
+ }
+
+ void VerifyTurnOffFlowStatusWebUIResponse(
+ size_t expected_total_calls,
+ const std::string& expected_callback_id,
+ const std::string& expected_status) {
+ EXPECT_EQ(expected_total_calls, web_ui()->call_data().size());
+
+ const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
+ EXPECT_EQ("cr.webUIResponse", data.function_name());
+
+ std::string callback_id;
+ ASSERT_TRUE(data.arg1()->GetAsString(&callback_id));
+ EXPECT_EQ(expected_callback_id, callback_id);
+
+ std::string actual_status;
+ ASSERT_TRUE(data.arg3()->GetAsString(&actual_status));
+ EXPECT_EQ(expected_status, actual_status);
+ }
+
+ private:
+ content::TestBrowserThreadBundle thread_bundle_;
+ std::unique_ptr<TestingProfile> profile_;
+ content::TestWebUI web_ui_;
+};
+
+TEST_F(EasyUnlockSettingsHandlerTest, OnlyCreatedWhenEasyUnlockAllowed) {
+ std::unique_ptr<EasyUnlockSettingsHandler> handler;
+ content::WebUIDataSource* data_source =
+ content::WebUIDataSource::Create("test-data-source");
+ content::WebUIDataSource::Add(profile(), data_source);
+ handler.reset(
+ EasyUnlockSettingsHandler::Create(data_source, profile()));
+ EXPECT_TRUE(handler.get());
+
+ fake_easy_unlock_service()->set_is_allowed(false);
+ handler.reset(EasyUnlockSettingsHandler::Create(data_source, profile()));
+ EXPECT_FALSE(handler.get());
+}
+
+TEST_F(EasyUnlockSettingsHandlerTest, EnabledStatus) {
+ std::unique_ptr<EasyUnlockSettingsHandler> handler;
+ handler.reset(new TestEasyUnlockSettingsHandler(profile()));
+ handler->set_web_ui(web_ui());
+
+ // Test the JS -> C++ -> JS callback path.
+ base::ListValue list_args;
+ list_args.AppendString("test-callback-id");
+ handler->HandleGetEnabledStatus(&list_args);
+
+ EXPECT_EQ(1U, web_ui()->call_data().size());
+
+ const content::TestWebUI::CallData& data = *web_ui()->call_data().back();
+ EXPECT_EQ("cr.webUIResponse", data.function_name());
+
+ std::string callback_id;
+ ASSERT_TRUE(data.arg1()->GetAsString(&callback_id));
+ EXPECT_EQ("test-callback-id", callback_id);
+
+ bool enabled_status = false;
+ ASSERT_TRUE(data.arg3()->GetAsBoolean(&enabled_status));
+ EXPECT_FALSE(enabled_status);
+
+ // Test the C++ -> JS push path.
+ handler->SendEnabledStatus();
+ VerifyEnabledStatusCallback(2U, false);
+
+ fake_easy_unlock_service()->set_is_enabled(true);
+ handler->SendEnabledStatus();
+ VerifyEnabledStatusCallback(3U, true);
+}
+
+TEST_F(EasyUnlockSettingsHandlerTest, TurnOffFlowStatus) {
+ std::unique_ptr<EasyUnlockSettingsHandler> handler;
+ handler.reset(new TestEasyUnlockSettingsHandler(profile()));
+ handler->set_web_ui(web_ui());
+
+ // Send an initial status query to turn on service observer.
+ base::ListValue list_args1;
+ list_args1.AppendString("test-callback-id-1");
+ handler->HandleGetEnabledStatus(&list_args1);
+ EXPECT_EQ(1U, web_ui()->call_data().size());
+
+ base::ListValue list_args2;
+ list_args2.AppendString("test-callback-id-2");
+ handler->HandleGetTurnOffFlowStatus(&list_args2);
+ VerifyTurnOffFlowStatusWebUIResponse(2U, "test-callback-id-2", "idle");
+
+ handler->HandleStartTurnOffFlow(nullptr);
+ VerifyTurnOffFlowStatusWebUIListenerCallback(3U, "pending");
+
+ base::ListValue list_args3;
+ list_args3.AppendString("test-callback-id-3");
+ handler->HandleGetTurnOffFlowStatus(&list_args3);
+ VerifyTurnOffFlowStatusWebUIResponse(4U, "test-callback-id-3", "pending");
+
+ handler->HandleCancelTurnOffFlow(nullptr);
+ VerifyTurnOffFlowStatusWebUIListenerCallback(5U, "idle");
+
+ fake_easy_unlock_service()->SetTurnOffFlowFailForTest();
+ VerifyTurnOffFlowStatusWebUIListenerCallback(6U, "server-error");
+
+ base::ListValue list_args4;
+ list_args4.AppendString("test-callback-id-4");
+ handler->HandleGetTurnOffFlowStatus(&list_args4);
+ VerifyTurnOffFlowStatusWebUIResponse(7U, "test-callback-id-4",
+ "server-error");
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc
new file mode 100644
index 00000000000..afcd3c13819
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.cc
@@ -0,0 +1,327 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.h"
+
+#include <algorithm>
+
+#include "base/bind.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/grit/generated_resources.h"
+#include "components/prefs/pref_service.h"
+#include "components/session_manager/core/session_manager.h"
+#include "content/public/common/service_manager_connection.h"
+#include "services/device/public/interfaces/constants.mojom.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "ui/base/l10n/l10n_util.h"
+
+using session_manager::SessionManager;
+using session_manager::SessionState;
+
+namespace chromeos {
+namespace settings {
+namespace {
+
+// The max number of fingerprints that can be stored.
+const int kMaxAllowedFingerprints = 5;
+
+std::unique_ptr<base::DictionaryValue> GetFingerprintsInfo(
+ const std::vector<std::string>& fingerprints_list) {
+ auto response = base::MakeUnique<base::DictionaryValue>();
+ auto fingerprints = base::MakeUnique<base::ListValue>();
+
+ DCHECK_LE(static_cast<int>(fingerprints_list.size()),
+ kMaxAllowedFingerprints);
+ for (auto& fingerprint_name: fingerprints_list) {
+ std::unique_ptr<base::Value> str =
+ base::MakeUnique<base::Value>(fingerprint_name);
+ fingerprints->Append(std::move(str));
+ }
+
+ response->Set("fingerprintsList", std::move(fingerprints));
+ response->SetBoolean("isMaxed", static_cast<int>(fingerprints_list.size()) >=
+ kMaxAllowedFingerprints);
+ return response;
+}
+
+} // namespace
+
+FingerprintHandler::FingerprintHandler(Profile* profile)
+ : profile_(profile), binding_(this), weak_ptr_factory_(this) {
+ service_manager::Connector* connector =
+ content::ServiceManagerConnection::GetForProcess()->GetConnector();
+ connector->BindInterface(device::mojom::kServiceName, &fp_service_);
+ fp_service_->AddFingerprintObserver(binding_.CreateInterfacePtrAndBind());
+ user_id_ = ProfileHelper::Get()->GetUserIdHashFromProfile(profile);
+ // SessionManager may not exist in some tests.
+ if (SessionManager::Get())
+ SessionManager::Get()->AddObserver(this);
+}
+
+FingerprintHandler::~FingerprintHandler() {
+ if (SessionManager::Get())
+ SessionManager::Get()->RemoveObserver(this);
+}
+
+void FingerprintHandler::RegisterMessages() {
+ web_ui()->RegisterMessageCallback(
+ "getFingerprintsList",
+ base::Bind(&FingerprintHandler::HandleGetFingerprintsList,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "getNumFingerprints",
+ base::Bind(&FingerprintHandler::HandleGetNumFingerprints,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "startEnroll",
+ base::Bind(&FingerprintHandler::HandleStartEnroll,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "cancelCurrentEnroll",
+ base::Bind(&FingerprintHandler::HandleCancelCurrentEnroll,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "getEnrollmentLabel",
+ base::Bind(&FingerprintHandler::HandleGetEnrollmentLabel,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "removeEnrollment",
+ base::Bind(&FingerprintHandler::HandleRemoveEnrollment,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "changeEnrollmentLabel",
+ base::Bind(&FingerprintHandler::HandleChangeEnrollmentLabel,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "startAuthentication",
+ base::Bind(&FingerprintHandler::HandleStartAuthentication,
+ base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ "endCurrentAuthentication",
+ base::Bind(&FingerprintHandler::HandleEndCurrentAuthentication,
+ base::Unretained(this)));
+}
+
+void FingerprintHandler::OnJavascriptAllowed() {}
+
+void FingerprintHandler::OnJavascriptDisallowed() {}
+
+void FingerprintHandler::OnRestarted() {}
+
+void FingerprintHandler::OnEnrollScanDone(uint32_t scan_result,
+ bool enroll_session_complete,
+ int percent_complete) {
+ AllowJavascript();
+ auto scan_attempt = base::MakeUnique<base::DictionaryValue>();
+ scan_attempt->SetInteger("result", scan_result);
+ scan_attempt->SetBoolean("isComplete", enroll_session_complete);
+ scan_attempt->SetInteger("percentComplete", percent_complete);
+
+ FireWebUIListener("on-fingerprint-scan-received", *scan_attempt);
+}
+
+void FingerprintHandler::OnAuthScanDone(
+ uint32_t scan_result,
+ const std::unordered_map<std::string, std::vector<std::string>>& matches) {
+ if (SessionManager::Get()->session_state() == SessionState::LOCKED)
+ return;
+
+ // When the user touches the sensor, highlight the label(s) that finger is
+ // associated with, if it is registered with this user.
+ auto it = matches.find(user_id_);
+ if (it == matches.end() || it->second.size() < 1)
+ return;
+
+ AllowJavascript();
+ auto fingerprint_ids = base::MakeUnique<base::ListValue>();
+
+ for (const std::string& matched_path : it->second) {
+ auto path_it = std::find(fingerprints_paths_.begin(),
+ fingerprints_paths_.end(), matched_path);
+ DCHECK(path_it != fingerprints_paths_.end());
+ fingerprint_ids->AppendInteger(
+ static_cast<int>(path_it - fingerprints_paths_.begin()));
+ }
+
+ auto fingerprint_attempt = base::MakeUnique<base::DictionaryValue>();
+ fingerprint_attempt->SetInteger("result", scan_result);
+ fingerprint_attempt->Set("indexes", std::move(fingerprint_ids));
+
+ FireWebUIListener("on-fingerprint-attempt-received", *fingerprint_attempt);
+}
+
+void FingerprintHandler::OnSessionFailed() {}
+
+void FingerprintHandler::OnSessionStateChanged() {
+ SessionState state = SessionManager::Get()->session_state();
+
+ AllowJavascript();
+ FireWebUIListener("on-screen-locked",
+ base::Value(state == SessionState::LOCKED));
+}
+
+void FingerprintHandler::HandleGetFingerprintsList(
+ const base::ListValue* args) {
+ CHECK_EQ(1U, args->GetSize());
+ std::string callback_id;
+ CHECK(args->GetString(0, &callback_id));
+
+ fp_service_->GetRecordsForUser(
+ user_id_, base::Bind(&FingerprintHandler::OnGetFingerprintsList,
+ weak_ptr_factory_.GetWeakPtr(), callback_id));
+}
+
+void FingerprintHandler::OnGetFingerprintsList(
+ const std::string& callback_id,
+ const std::unordered_map<std::string, std::string>&
+ fingerprints_list_mapping) {
+ AllowJavascript();
+ fingerprints_labels_.clear();
+ fingerprints_paths_.clear();
+ for (auto it = fingerprints_list_mapping.begin();
+ it != fingerprints_list_mapping.end(); ++it) {
+ fingerprints_paths_.push_back(it->first);
+ fingerprints_labels_.push_back(it->second);
+ }
+
+ profile_->GetPrefs()->SetInteger(prefs::kQuickUnlockFingerprintRecord,
+ fingerprints_list_mapping.size());
+
+ std::unique_ptr<base::DictionaryValue> fingerprint_info =
+ GetFingerprintsInfo(fingerprints_labels_);
+ ResolveJavascriptCallback(base::Value(callback_id), *fingerprint_info);
+}
+
+void FingerprintHandler::HandleGetNumFingerprints(const base::ListValue* args) {
+ AllowJavascript();
+
+ CHECK_EQ(1U, args->GetSize());
+ std::string callback_id;
+ CHECK(args->GetString(0, &callback_id));
+
+ int fingerprints_num =
+ profile_->GetPrefs()->GetInteger(prefs::kQuickUnlockFingerprintRecord);
+
+ ResolveJavascriptCallback(base::Value(callback_id),
+ base::Value(fingerprints_num));
+}
+
+void FingerprintHandler::HandleStartEnroll(const base::ListValue* args) {
+ // Determines what the newly added fingerprint's name should be.
+ for (int i = 1; i <= kMaxAllowedFingerprints; ++i) {
+ std::string fingerprint_name = l10n_util::GetStringFUTF8(
+ IDS_SETTINGS_PEOPLE_LOCK_SCREEN_NEW_FINGERPRINT_DEFAULT_NAME,
+ base::IntToString16(i));
+ if (std::find(fingerprints_labels_.begin(), fingerprints_labels_.end(),
+ fingerprint_name) == fingerprints_labels_.end()) {
+ fp_service_->StartEnrollSession(user_id_, fingerprint_name);
+ break;
+ }
+ }
+}
+
+void FingerprintHandler::HandleCancelCurrentEnroll(
+ const base::ListValue* args) {
+ fp_service_->CancelCurrentEnrollSession(
+ base::Bind(&FingerprintHandler::OnCancelCurrentEnrollSession,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void FingerprintHandler::OnCancelCurrentEnrollSession(bool success) {
+ if (!success)
+ LOG(ERROR) << "Failed to cancel current fingerprint enroll session.";
+}
+
+void FingerprintHandler::HandleGetEnrollmentLabel(const base::ListValue* args) {
+ CHECK_EQ(2U, args->GetSize());
+ std::string callback_id;
+ int index;
+ CHECK(args->GetString(0, &callback_id));
+ CHECK(args->GetInteger(1, &index));
+
+ DCHECK_LT(index, static_cast<int>(fingerprints_labels_.size()));
+ fp_service_->RequestRecordLabel(
+ fingerprints_paths_[index],
+ base::Bind(&FingerprintHandler::OnRequestRecordLabel,
+ weak_ptr_factory_.GetWeakPtr(), callback_id));
+}
+
+void FingerprintHandler::OnRequestRecordLabel(const std::string& callback_id,
+ const std::string& label) {
+ AllowJavascript();
+ ResolveJavascriptCallback(base::Value(callback_id), base::Value(label));
+}
+
+void FingerprintHandler::HandleRemoveEnrollment(const base::ListValue* args) {
+ CHECK_EQ(2U, args->GetSize());
+ std::string callback_id;
+ int index;
+ CHECK(args->GetString(0, &callback_id));
+ CHECK(args->GetInteger(1, &index));
+
+ DCHECK_LT(index, static_cast<int>(fingerprints_paths_.size()));
+ fp_service_->RemoveRecord(
+ fingerprints_paths_[index],
+ base::Bind(&FingerprintHandler::OnRemoveRecord,
+ weak_ptr_factory_.GetWeakPtr(), callback_id));
+}
+
+void FingerprintHandler::OnRemoveRecord(const std::string& callback_id,
+ bool success) {
+ if (!success)
+ LOG(ERROR) << "Failed to remove fingerprint record.";
+ AllowJavascript();
+ ResolveJavascriptCallback(base::Value(callback_id), base::Value(success));
+}
+
+void FingerprintHandler::HandleChangeEnrollmentLabel(
+ const base::ListValue* args) {
+ CHECK_EQ(3U, args->GetSize());
+ std::string callback_id;
+ int index;
+ std::string new_label;
+
+ CHECK(args->GetString(0, &callback_id));
+ CHECK(args->GetInteger(1, &index));
+ CHECK(args->GetString(2, &new_label));
+
+ fp_service_->SetRecordLabel(
+ new_label, fingerprints_paths_[index],
+ base::Bind(&FingerprintHandler::OnSetRecordLabel,
+ weak_ptr_factory_.GetWeakPtr(), callback_id));
+}
+
+void FingerprintHandler::OnSetRecordLabel(const std::string& callback_id,
+ bool success) {
+ if (!success)
+ LOG(ERROR) << "Failed to set fingerprint record label.";
+ AllowJavascript();
+ ResolveJavascriptCallback(base::Value(callback_id), base::Value(success));
+}
+
+void FingerprintHandler::HandleStartAuthentication(
+ const base::ListValue* args) {
+ fp_service_->StartAuthSession();
+}
+
+void FingerprintHandler::HandleEndCurrentAuthentication(
+ const base::ListValue* args) {
+ fp_service_->EndCurrentAuthSession(
+ base::Bind(&FingerprintHandler::OnEndCurrentAuthSession,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void FingerprintHandler::OnEndCurrentAuthSession(bool success) {
+ if (!success)
+ LOG(ERROR) << "Failed to end current fingerprint authentication session.";
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.h
new file mode 100644
index 00000000000..5c296d69fe7
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.h
@@ -0,0 +1,90 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FINGERPRINT_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FINGERPRINT_HANDLER_H_
+
+#include <unordered_map>
+
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "components/session_manager/core/session_manager_observer.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "services/device/public/interfaces/fingerprint.mojom.h"
+
+class Profile;
+
+namespace base {
+class ListValue;
+} // namespace base
+
+namespace chromeos {
+namespace settings {
+
+// Chrome OS fingerprint setup settings page UI handler.
+class FingerprintHandler : public ::settings::SettingsPageUIHandler,
+ public device::mojom::FingerprintObserver,
+ public session_manager::SessionManagerObserver {
+ public:
+ explicit FingerprintHandler(Profile* profile);
+ ~FingerprintHandler() override;
+
+ // SettingsPageUIHandler overrides:
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override;
+ void OnJavascriptDisallowed() override;
+
+ private:
+ using AttemptMatches =
+ std::unordered_map<std::string, std::vector<std::string>>;
+
+ // device::mojom::FingerprintObserver:
+ void OnRestarted() override;
+ void OnEnrollScanDone(uint32_t scan_result,
+ bool enroll_session_complete,
+ int percent_complete) override;
+ void OnAuthScanDone(uint32_t scan_result,
+ const AttemptMatches& matches) override;
+ void OnSessionFailed() override;
+
+ // session_manager::SessionManagerObserver:
+ void OnSessionStateChanged() override;
+
+ void HandleGetFingerprintsList(const base::ListValue* args);
+ void HandleGetNumFingerprints(const base::ListValue* args);
+ void HandleStartEnroll(const base::ListValue* args);
+ void HandleCancelCurrentEnroll(const base::ListValue* args);
+ void HandleGetEnrollmentLabel(const base::ListValue* args);
+ void HandleRemoveEnrollment(const base::ListValue* args);
+ void HandleChangeEnrollmentLabel(const base::ListValue* args);
+ void HandleStartAuthentication(const base::ListValue* args);
+ void HandleEndCurrentAuthentication(const base::ListValue* args);
+
+ void OnGetFingerprintsList(const std::string& callback_id,
+ const std::unordered_map<std::string, std::string>&
+ fingerprints_list_mapping);
+ void OnRequestRecordLabel(const std::string& callback_id,
+ const std::string& label);
+ void OnCancelCurrentEnrollSession(bool success);
+ void OnRemoveRecord(const std::string& callback_id, bool success);
+ void OnSetRecordLabel(const std::string& callback_id, bool success);
+ void OnEndCurrentAuthSession(bool success);
+
+ Profile* profile_; // unowned
+
+ std::vector<std::string> fingerprints_labels_;
+ std::vector<std::string> fingerprints_paths_;
+ std::string user_id_;
+
+ device::mojom::FingerprintPtr fp_service_;
+ mojo::Binding<device::mojom::FingerprintObserver> binding_;
+
+ base::WeakPtrFactory<FingerprintHandler> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(FingerprintHandler);
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_FINGERPRINT_HANDLER_H_
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc
new file mode 100644
index 00000000000..1af49e99b48
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.cc
@@ -0,0 +1,132 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/webui/settings/chromeos/internet_handler.h"
+
+#include "base/bind.h"
+#include "base/values.h"
+#include "chrome/browser/chromeos/options/network_config_view.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/chromeos/ui/choose_mobile_network_dialog.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chromeos/network/network_state.h"
+#include "chromeos/network/network_state_handler.h"
+#include "components/onc/onc_constants.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_ui.h"
+#include "extensions/browser/api/vpn_provider/vpn_service.h"
+#include "extensions/browser/api/vpn_provider/vpn_service_factory.h"
+#include "third_party/cros_system_api/dbus/service_constants.h"
+
+namespace chromeos {
+
+namespace {
+
+const char kAddNetworkMessage[] = "addNetwork";
+const char kConfigureNetworkMessage[] = "configureNetwork";
+
+std::string ServicePathFromGuid(const std::string& guid) {
+ const NetworkState* network =
+ NetworkHandler::Get()->network_state_handler()->GetNetworkStateFromGuid(
+ guid);
+ return network ? network->path() : "";
+}
+
+Profile* GetProfileForPrimaryUser() {
+ return ProfileHelper::Get()->GetProfileByUser(
+ user_manager::UserManager::Get()->GetPrimaryUser());
+}
+
+} // namespace
+
+namespace settings {
+
+InternetHandler::InternetHandler() {}
+
+InternetHandler::~InternetHandler() {}
+
+void InternetHandler::RegisterMessages() {
+ // TODO(stevenjb): Eliminate once network configuration UI is integrated
+ // into settings.
+ web_ui()->RegisterMessageCallback(
+ kAddNetworkMessage,
+ base::Bind(&InternetHandler::AddNetwork, base::Unretained(this)));
+ web_ui()->RegisterMessageCallback(
+ kConfigureNetworkMessage,
+ base::Bind(&InternetHandler::ConfigureNetwork, base::Unretained(this)));
+}
+
+void InternetHandler::OnJavascriptAllowed() {}
+
+void InternetHandler::OnJavascriptDisallowed() {}
+
+void InternetHandler::AddNetwork(const base::ListValue* args) {
+ std::string onc_type;
+ if (args->GetSize() < 1 || !args->GetString(0, &onc_type)) {
+ NOTREACHED() << "Invalid args for: " << kAddNetworkMessage;
+ return;
+ }
+
+ if (onc_type == ::onc::network_type::kVPN) {
+ std::string extension_id;
+ if (args->GetSize() >= 2)
+ args->GetString(1, &extension_id);
+ if (extension_id.empty()) {
+ // Show the "add network" dialog for the built-in OpenVPN/L2TP provider.
+ NetworkConfigView::ShowForType(shill::kTypeVPN, GetNativeWindow());
+ return;
+ }
+ // Request that the third-party VPN provider identified by |provider_id|
+ // show its "add network" dialog.
+ VpnServiceFactory::GetForBrowserContext(GetProfileForPrimaryUser())
+ ->SendShowAddDialogToExtension(extension_id);
+ } else if (onc_type == ::onc::network_type::kWiFi) {
+ NetworkConfigView::ShowForType(shill::kTypeWifi, GetNativeWindow());
+ } else if (onc_type == ::onc::network_type::kCellular) {
+ ChooseMobileNetworkDialog::ShowDialog(GetNativeWindow());
+ } else {
+ LOG(ERROR) << "Unsupported type for: " << kAddNetworkMessage;
+ }
+}
+
+void InternetHandler::ConfigureNetwork(const base::ListValue* args) {
+ std::string guid;
+ if (args->GetSize() < 1 || !args->GetString(0, &guid)) {
+ NOTREACHED() << "Invalid args for: " << kConfigureNetworkMessage;
+ return;
+ }
+
+ const std::string service_path = ServicePathFromGuid(guid);
+ if (service_path.empty()) {
+ LOG(ERROR) << "Network not found: " << guid;
+ return;
+ }
+
+ const NetworkState* network =
+ NetworkHandler::Get()->network_state_handler()->GetNetworkState(
+ service_path);
+ if (!network) {
+ LOG(ERROR) << "Network not found with service_path: " << service_path;
+ return;
+ }
+
+ if (network->type() == shill::kTypeVPN &&
+ network->vpn_provider_type() == shill::kProviderThirdPartyVpn) {
+ // Request that the third-party VPN provider used by the |network| show a
+ // configuration dialog for it.
+ VpnServiceFactory::GetForBrowserContext(GetProfileForPrimaryUser())
+ ->SendShowConfigureDialogToExtension(
+ network->third_party_vpn_provider_extension_id(), network->name());
+ return;
+ }
+
+ NetworkConfigView::ShowForNetworkId(network->guid(), GetNativeWindow());
+}
+
+gfx::NativeWindow InternetHandler::GetNativeWindow() const {
+ return web_ui()->GetWebContents()->GetTopLevelNativeWindow();
+}
+
+} // namespace settings
+} // namespace chromeos
diff --git a/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.h b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.h
new file mode 100644
index 00000000000..64ceabfe29b
--- /dev/null
+++ b/chromium/chrome/browser/ui/webui/settings/chromeos/internet_handler.h
@@ -0,0 +1,41 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_INTERNET_HANDLER_H_
+#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_INTERNET_HANDLER_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
+#include "ui/gfx/native_widget_types.h"
+
+namespace chromeos {
+namespace settings {
+
+// Chrome OS Internet settings page UI handler.
+class InternetHandler : public ::settings::SettingsPageUIHandler {
+ public:
+ InternetHandler();
+ ~InternetHandler() override;
+
+ // SettingsPageUIHandler implementation.
+ void RegisterMessages() override;
+ void OnJavascriptAllowed() override;
+ void OnJavascriptDisallowed() override;
+
+ private:
+ // Settings JS handlers.
+ void AddNetwork(const base::ListValue* args);
+ void ConfigureNetwork(const base::ListValue* args);
+
+ gfx::NativeWindow GetNativeWindow() const;
+
+ DISALLOW_COPY_AND_ASSIGN(InternetHandler);
+};
+
+} // namespace settings
+} // namespace chromeos
+
+#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_INTERNET_HANDLER_H_