diff options
20 files changed, 442 insertions, 64 deletions
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 5307661..3922c6d 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp @@ -1582,14 +1582,21 @@ Press any key to continue exploring. <message name="IDS_LOGIN_PREVIOUS_PASSWORD" desc="Password field text on the password changed dialog"> Previous password </message> - <message name="IDS_LOGIN_UNRECOVERABLE_CRYPTOHOME_ERROR_MESSAGE" desc="Message text for the fatal cryptohome error dialog box"> - We're very sorry, but a serious error has occurred and your profile will need to be recreated to continue. Don't worry, your account is safe, but unfortunately, your local data and files on this device may have been lost. + <message name="IDS_LOGIN_UNRECOVERABLE_CRYPTOHOME_ERROR_TITLE" desc="Title for the fatal cryptohome error dialog box"> + Could not sign in + </message> + <message name="IDS_LOGIN_UNRECOVERABLE_CRYPTOHOME_ERROR_MESSAGE" desc="Message for the fatal cryptohome error dialog box"> + We're very sorry, but a serious error has occurred and your profile on this device will need to be re-created to continue.<ph name="BR"><br></ph> + <ph name="BR"><br></ph> + Don't worry, your account is safe, but unfortunately, your local data and files on this device may have been lost.<ph name="BR"><br></ph> + <ph name="BR"><br></ph> + Please send feedback to help us prevent this issue in the future. </message> <message name="IDS_LOGIN_UNRECOVERABLE_CRYPTOHOME_ERROR_CONTINUE" desc="Label of the button to continue with re-creating cryptohome for the fatal cryptohome error dialog box"> Continue </message> - <message name="IDS_LOGIN_UNRECOVERABLE_CRYPTOHOME_ERROR_SEND_FEEDBACK" desc="Label of the checkbox to send feedback for the fatal cryptohome error dialog box"> - Send anonymized system information to help us fix this issue + <message name="IDS_LOGIN_UNRECOVERABLE_CRYPTOHOME_ERROR_WAIT_MESSAGE" desc="Message to show when the fatal cryptohome error dialog box is waiting for user profile re-creation to be closed."> + Re-creating profile, please wait... </message> <message name="IDS_LOGIN_SAML_NOTICE" desc="Text message displayed above SAML portal to early indicate that the user is being redirected to another sign-in provider. This is the version of the string used in the GAIA flow."> This sign-in service is hosted by <ph name="SAML_DOMAIN">$1<ex>saml.com</ex></ph> diff --git a/chrome/browser/chromeos/login/test/app_window_waiter.cc b/chrome/browser/chromeos/login/test/app_window_waiter.cc index 75a3397..0308b7d 100644 --- a/chrome/browser/chromeos/login/test/app_window_waiter.cc +++ b/chrome/browser/chromeos/login/test/app_window_waiter.cc @@ -10,7 +10,7 @@ namespace chromeos { AppWindowWaiter::AppWindowWaiter(extensions::AppWindowRegistry* registry, const std::string& app_id) - : registry_(registry), app_id_(app_id), window_(NULL) { + : registry_(registry), app_id_(app_id) { registry_->AddObserver(this); } @@ -23,18 +23,43 @@ extensions::AppWindow* AppWindowWaiter::Wait() { if (window_) return window_; - run_loop_.Run(); + wait_type_ = WAIT_FOR_ADDED; + run_loop_.reset(new base::RunLoop); + run_loop_->Run(); + + return window_; +} + +extensions::AppWindow* AppWindowWaiter::WaitForShown() { + window_ = registry_->GetCurrentAppWindowForApp(app_id_); + if (window_ && !window_->is_hidden()) + return window_; + + wait_type_ = WAIT_FOR_SHOWN; + run_loop_.reset(new base::RunLoop); + run_loop_->Run(); return window_; } void AppWindowWaiter::OnAppWindowAdded(extensions::AppWindow* app_window) { - if (!run_loop_.running()) + if (wait_type_ != WAIT_FOR_ADDED || !run_loop_ || !run_loop_->running()) + return; + + if (app_window->extension_id() == app_id_) { + window_ = app_window; + run_loop_->Quit(); + } +} + +void AppWindowWaiter::OnAppWindowShown(extensions::AppWindow* app_window, + bool was_hidden) { + if (wait_type_ != WAIT_FOR_SHOWN || !run_loop_ || !run_loop_->running()) return; if (app_window->extension_id() == app_id_) { window_ = app_window; - run_loop_.Quit(); + run_loop_->Quit(); } } diff --git a/chrome/browser/chromeos/login/test/app_window_waiter.h b/chrome/browser/chromeos/login/test/app_window_waiter.h index bb2bfc8..90db4dd 100644 --- a/chrome/browser/chromeos/login/test/app_window_waiter.h +++ b/chrome/browser/chromeos/login/test/app_window_waiter.h @@ -9,6 +9,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/memory/scoped_ptr.h" #include "base/run_loop.h" #include "extensions/browser/app_window/app_window_registry.h" @@ -26,16 +27,29 @@ class AppWindowWaiter : public extensions::AppWindowRegistry::Observer { const std::string& app_id); ~AppWindowWaiter() override; + // Waits for an AppWindow of the app to be added. extensions::AppWindow* Wait(); + // Waits for an AppWindow of the app to be shown. + extensions::AppWindow* WaitForShown(); + // AppWindowRegistry::Observer: void OnAppWindowAdded(extensions::AppWindow* app_window) override; + void OnAppWindowShown(extensions::AppWindow* app_window, + bool was_hidden) override; private: - extensions::AppWindowRegistry* registry_; - std::string app_id_; - base::RunLoop run_loop_; - extensions::AppWindow* window_; + enum WaitType { + WAIT_FOR_NONE, + WAIT_FOR_ADDED, + WAIT_FOR_SHOWN, + }; + + extensions::AppWindowRegistry* const registry_; + const std::string app_id_; + scoped_ptr<base::RunLoop> run_loop_; + WaitType wait_type_ = WAIT_FOR_NONE; + extensions::AppWindow* window_ = nullptr; DISALLOW_COPY_AND_ASSIGN(AppWindowWaiter); }; diff --git a/chrome/browser/chromeos/login/ui/login_feedback.cc b/chrome/browser/chromeos/login/ui/login_feedback.cc new file mode 100644 index 0000000..bf58ed0 --- /dev/null +++ b/chrome/browser/chromeos/login/ui/login_feedback.cc @@ -0,0 +1,197 @@ +// 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/chromeos/login/ui/login_feedback.h" + +#include "base/bind.h" +#include "base/time/time.h" +#include "chrome/browser/chromeos/login/ui/login_display_host.h" +#include "chrome/browser/extensions/api/feedback_private/feedback_private_api.h" +#include "chrome/browser/extensions/component_loader.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/extensions/extension_constants.h" +#include "content/public/browser/browser_thread.h" +#include "extensions/browser/app_window/app_window.h" +#include "extensions/browser/app_window/app_window_registry.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/browser/extension_system.h" +#include "extensions/common/extension.h" +#include "grit/browser_resources.h" +#include "ui/aura/window.h" +#include "ui/views/widget/widget.h" +#include "ui/wm/core/window_util.h" + +namespace chromeos { + +namespace { + +extensions::ComponentLoader* GetComponentLoader( + content::BrowserContext* context) { + extensions::ExtensionSystem* extension_system = + extensions::ExtensionSystem::Get(context); + ExtensionService* extension_service = extension_system->extension_service(); + return extension_service->component_loader(); +} + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// +// LoginFeedback::ScopedFeedbackExtension + +class LoginFeedback::ScopedFeedbackExtension + : public extensions::ExtensionRegistryObserver { + public: + explicit ScopedFeedbackExtension(LoginFeedback* owner); + ~ScopedFeedbackExtension() override; + + // extensions::ExtensionRegistryObserver + void OnExtensionReady(content::BrowserContext* browser_context, + const extensions::Extension* extension) override; + + private: + LoginFeedback* const owner_; + DISALLOW_COPY_AND_ASSIGN(ScopedFeedbackExtension); +}; + +LoginFeedback::ScopedFeedbackExtension::ScopedFeedbackExtension( + LoginFeedback* owner) + : owner_(owner) { + Profile* profile = owner_->profile_; + extensions::ExtensionRegistry::Get(profile)->AddObserver(this); + + extensions::ComponentLoader* component_loader = GetComponentLoader(profile); + DCHECK(!component_loader->Exists(extension_misc::kFeedbackExtensionId)) + << "Feedback extension is already loaded. Is there any other " + "LoginFeedback instance running?"; + component_loader->Add(IDR_FEEDBACK_MANIFEST, + base::FilePath(FILE_PATH_LITERAL("feedback"))); +} + +LoginFeedback::ScopedFeedbackExtension::~ScopedFeedbackExtension() { + Profile* profile = owner_->profile_; + extensions::ExtensionRegistry::Get(profile)->RemoveObserver(this); + GetComponentLoader(profile)->Remove(extension_misc::kFeedbackExtensionId); +} + +void LoginFeedback::ScopedFeedbackExtension::OnExtensionReady( + content::BrowserContext* browser_context, + const extensions::Extension* extension) { + if (extension->id() != extension_misc::kFeedbackExtensionId) + return; + owner_->OnFeedbackExtensionReady(); +} + +//////////////////////////////////////////////////////////////////////////////// +// LoginFeedback::FeedbackWindowHandler + +class LoginFeedback::FeedbackWindowHandler + : public extensions::AppWindowRegistry::Observer { + public: + explicit FeedbackWindowHandler(LoginFeedback* owner); + ~FeedbackWindowHandler() override; + + bool HasFeedbackAppWindow() const; + + // extensions::AppWindowRegistry::Observer + void OnAppWindowAdded(extensions::AppWindow* app_window) override; + void OnAppWindowRemoved(extensions::AppWindow* app_window) override; + + private: + LoginFeedback* const owner_; + extensions::AppWindowRegistry* const window_registry_; + + DISALLOW_COPY_AND_ASSIGN(FeedbackWindowHandler); +}; + +LoginFeedback::FeedbackWindowHandler::FeedbackWindowHandler( + LoginFeedback* owner) + : owner_(owner), + window_registry_(extensions::AppWindowRegistry::Get(owner_->profile_)) { + window_registry_->AddObserver(this); +} + +LoginFeedback::FeedbackWindowHandler::~FeedbackWindowHandler() { + window_registry_->RemoveObserver(this); +} + +bool LoginFeedback::FeedbackWindowHandler::HasFeedbackAppWindow() const { + return !window_registry_ + ->GetAppWindowsForApp(extension_misc::kFeedbackExtensionId) + .empty(); +} + +void LoginFeedback::FeedbackWindowHandler::OnAppWindowAdded( + extensions::AppWindow* app_window) { + if (app_window->extension_id() != extension_misc::kFeedbackExtensionId) + return; + + // Move the feedback window to the same container as the login screen and make + // it a transient child of the login screen. + views::Widget::ReparentNativeView( + app_window->GetNativeWindow(), + LoginDisplayHost::default_host()->GetNativeWindow()->parent()); + wm::AddTransientChild(LoginDisplayHost::default_host()->GetNativeWindow(), + app_window->GetNativeWindow()); +} + +void LoginFeedback::FeedbackWindowHandler::OnAppWindowRemoved( + extensions::AppWindow* app_window) { + if (app_window->extension_id() != extension_misc::kFeedbackExtensionId) + return; + + if (!HasFeedbackAppWindow()) + owner_->OnFeedbackFinished(); +} + +//////////////////////////////////////////////////////////////////////////////// +// LoginFeedback + +LoginFeedback::LoginFeedback(Profile* signin_profile) + : profile_(signin_profile), weak_factory_(this) {} + +LoginFeedback::~LoginFeedback() {} + +void LoginFeedback::Request(const std::string& description, + const base::Closure& finished_callback) { + description_ = description; + finished_callback_ = finished_callback; + + feedback_extension_.reset(new ScopedFeedbackExtension(this)); +} + +void LoginFeedback::OnFeedbackExtensionReady() { + feedback_window_handler_.reset(new FeedbackWindowHandler(this)); + EnsureFeedbackUI(); +} + +void LoginFeedback::EnsureFeedbackUI() { + // Bail if any feedback app window is opened. + if (feedback_window_handler_->HasFeedbackAppWindow()) + return; + + extensions::FeedbackPrivateAPI* api = + extensions::FeedbackPrivateAPI::GetFactoryInstance()->Get(profile_); + api->RequestFeedbackForFlow( + description_, "Login", GURL(), + extensions::api::feedback_private::FeedbackFlow::FEEDBACK_FLOW_LOGIN); + + // Check feedback app window shortly after to ensure it is opened. There is + // some racing between the event dispatching and the starting of the + // background page. This is a poor man's way to make sure the event is + // delivered. + // TODO(xiyuan): Investigate why the occasional event lost and remove this. + const int kCheckDelaySecond = 1; + content::BrowserThread::PostDelayedTask( + content::BrowserThread::UI, FROM_HERE, + base::Bind(&LoginFeedback::EnsureFeedbackUI, weak_factory_.GetWeakPtr()), + base::TimeDelta::FromSeconds(kCheckDelaySecond)); +} + +void LoginFeedback::OnFeedbackFinished() { + if (!finished_callback_.is_null()) + finished_callback_.Run(); +} + +} // namespace chromeos diff --git a/chrome/browser/chromeos/login/ui/login_feedback.h b/chrome/browser/chromeos/login/ui/login_feedback.h new file mode 100644 index 0000000..80f8731 --- /dev/null +++ b/chrome/browser/chromeos/login/ui/login_feedback.h @@ -0,0 +1,65 @@ +// 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_CHROMEOS_LOGIN_UI_LOGIN_FEEDBACK_H_ +#define CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_FEEDBACK_H_ + +#include <string> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" + +class Profile; + +namespace chromeos { + +// Show the feedback UI to collect a feedback on the login screen. Note that +// it dynamically loads/unloads the feedback extension on the signin profile, +// there should only be one instance live of this class. Otherwise, they would +// stamp on each other toes and not function properly. +class LoginFeedback { + public: + explicit LoginFeedback(Profile* signin_profile); + ~LoginFeedback(); + + // Request to show the feedback UI with |description|. |finished_callback| + // will be invoked when the feedback UI is closed, either cancel or send the + // feedback. + void Request(const std::string& description, + const base::Closure& finished_callback); + + private: + // Loads and unloads the feedback extension on the signin profile. + class ScopedFeedbackExtension; + + // Makes the feedback UI windows on top of login screen and watches when + // all feedback windows are closed. + class FeedbackWindowHandler; + + // Invoked by ScopedFeedbackExtension when feedback extension is ready. + void OnFeedbackExtensionReady(); + + // Invoked by FeedbackWindowHandler when all feedback windows are closed. + void OnFeedbackFinished(); + + // Ensures feedback UI is created. + void EnsureFeedbackUI(); + + Profile* const profile_; + std::string description_; + base::Closure finished_callback_; + + scoped_ptr<ScopedFeedbackExtension> feedback_extension_; + scoped_ptr<FeedbackWindowHandler> feedback_window_handler_; + + base::WeakPtrFactory<LoginFeedback> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(LoginFeedback); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_LOGIN_UI_LOGIN_FEEDBACK_H_ diff --git a/chrome/browser/chromeos/login/ui/login_feedback_browsertest.cc b/chrome/browser/chromeos/login/ui/login_feedback_browsertest.cc new file mode 100644 index 0000000..2b2055b --- /dev/null +++ b/chrome/browser/chromeos/login/ui/login_feedback_browsertest.cc @@ -0,0 +1,52 @@ +// 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/chromeos/login/ui/login_feedback.h" + +#include "ash/wm/window_util.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "base/run_loop.h" +#include "chrome/browser/chromeos/login/login_manager_test.h" +#include "chrome/browser/chromeos/login/test/app_window_waiter.h" +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#include "chrome/common/extensions/extension_constants.h" +#include "extensions/browser/app_window/app_window.h" +#include "extensions/browser/app_window/app_window_registry.h" +#include "extensions/browser/app_window/native_app_window.h" +#include "ui/aura/client/focus_client.h" + +namespace chromeos { + +class LoginFeedbackTest : public LoginManagerTest { + public: + LoginFeedbackTest() : LoginManagerTest(true) {} + ~LoginFeedbackTest() override {} + + private: + DISALLOW_COPY_AND_ASSIGN(LoginFeedbackTest); +}; + +// Test feedback UI shows up and is active. +IN_PROC_BROWSER_TEST_F(LoginFeedbackTest, Basic) { + Profile* const profile = ProfileHelper::GetSigninProfile(); + scoped_ptr<LoginFeedback> login_feedback(new LoginFeedback(profile)); + + base::RunLoop run_loop; + login_feedback->Request("Test feedback", run_loop.QuitClosure()); + + extensions::AppWindow* feedback_window = + AppWindowWaiter(extensions::AppWindowRegistry::Get(profile), + extension_misc::kFeedbackExtensionId) + .WaitForShown(); + ASSERT_NE(nullptr, feedback_window); + EXPECT_FALSE(feedback_window->is_hidden()); + + EXPECT_EQ(feedback_window->GetNativeWindow(), ash::wm::GetActiveWindow()); + + feedback_window->GetBaseWindow()->Close(); + run_loop.Run(); +} + +} // namespace chromeos diff --git a/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc b/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc index b541db5..168de50 100644 --- a/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc +++ b/chrome/browser/extensions/api/feedback_private/feedback_browsertest.cc @@ -11,6 +11,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/extensions/api/feedback_private.h" +#include "chrome/common/extensions/extension_constants.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test_utils.h" @@ -48,7 +49,7 @@ class FeedbackTest : public ExtensionBrowserTest { bool IsFeedbackAppAvailable() { return extensions::EventRouter::Get(browser()->profile()) ->ExtensionHasEventListener( - kFeedbackExtensionId, + extension_misc::kFeedbackExtensionId, extensions::api::feedback_private::OnFeedbackRequested::kEventName); } @@ -66,7 +67,8 @@ class FeedbackTest : public ExtensionBrowserTest { ASSERT_TRUE(window); const Extension* feedback_app = window->GetExtension(); ASSERT_TRUE(feedback_app); - EXPECT_EQ(feedback_app->id(), std::string(kFeedbackExtensionId)); + EXPECT_EQ(feedback_app->id(), + std::string(extension_misc::kFeedbackExtensionId)); } private: diff --git a/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc b/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc index 4e375ae..061742f 100644 --- a/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc +++ b/chrome/browser/extensions/api/feedback_private/feedback_private_api.cc @@ -19,6 +19,7 @@ #include "chrome/browser/extensions/api/feedback_private/feedback_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/signin_manager_factory.h" +#include "chrome/common/extensions/extension_constants.h" #include "chrome/grit/generated_resources.h" #include "components/feedback/tracing_manager.h" #include "components/signin/core/browser/signin_manager.h" @@ -52,8 +53,6 @@ using feedback_private::SystemInformation; using feedback_private::FeedbackInfo; using feedback_private::FeedbackFlow; -char kFeedbackExtensionId[] = "gfdkimpbcpahaombhbimeihdjnejgicl"; - static base::LazyInstance<BrowserContextKeyedAPIFactory<FeedbackPrivateAPI> > g_factory = LAZY_INSTANCE_INITIALIZER; @@ -110,7 +109,8 @@ void FeedbackPrivateAPI::RequestFeedbackForFlow( event->restrict_to_browser_context = browser_context_; EventRouter::Get(browser_context_) - ->DispatchEventToExtension(kFeedbackExtensionId, std::move(event)); + ->DispatchEventToExtension(extension_misc::kFeedbackExtensionId, + std::move(event)); } } diff --git a/chrome/browser/extensions/api/feedback_private/feedback_private_api.h b/chrome/browser/extensions/api/feedback_private/feedback_private_api.h index 1e59cd5..bf21cfb 100644 --- a/chrome/browser/extensions/api/feedback_private/feedback_private_api.h +++ b/chrome/browser/extensions/api/feedback_private/feedback_private_api.h @@ -12,8 +12,6 @@ namespace extensions { -extern char kFeedbackExtensionId[]; - class FeedbackService; using extensions::api::feedback_private::SystemInformation; diff --git a/chrome/browser/resources/chromeos/login/screen_unrecoverable_cryptohome_error.html b/chrome/browser/resources/chromeos/login/screen_unrecoverable_cryptohome_error.html index 11a6f35..7901074 100644 --- a/chrome/browser/resources/chromeos/login/screen_unrecoverable_cryptohome_error.html +++ b/chrome/browser/resources/chromeos/login/screen_unrecoverable_cryptohome_error.html @@ -4,6 +4,8 @@ <unrecoverable-cryptohome-error-card id="unrecoverable-cryptohome-error-card"> </unrecoverable-cryptohome-error-card> <div id="unrecoverable-cryptohome-error-busy" class="step-loading" hidden> - <throbber-notice i18n-values="text:gaiaLoading"></throbber-notice> + <throbber-notice + i18n-values="text:unrecoverableCryptohomeErrorRecreatingProfile"> + </throbber-notice> </div> </div> diff --git a/chrome/browser/resources/chromeos/login/screen_unrecoverable_cryptohome_error.js b/chrome/browser/resources/chromeos/login/screen_unrecoverable_cryptohome_error.js index 42dd380..a00d536 100644 --- a/chrome/browser/resources/chromeos/login/screen_unrecoverable_cryptohome_error.js +++ b/chrome/browser/resources/chromeos/login/screen_unrecoverable_cryptohome_error.js @@ -6,7 +6,8 @@ login.createScreen('UnrecoverableCryptohomeErrorScreen', 'unrecoverable-cryptohome-error', function() { return { EXTERNAL_API: [ - 'show' + 'show', + 'resumeAfterFeedbackUI' ], /** @override */ @@ -16,11 +17,8 @@ login.createScreen('UnrecoverableCryptohomeErrorScreen', this.card_.addEventListener('done', function(e) { this.setLoading_(true); - if (e.detail.shouldSendFeedback) { - chrome.send('sendFeedbackAndResyncUserData'); - } else { - chrome.send('resyncUserData'); - } + $('oobe').hidden = true; // Hide while showing the feedback UI. + chrome.send('sendFeedbackAndResyncUserData'); }.bind(this)); }, @@ -34,13 +32,21 @@ login.createScreen('UnrecoverableCryptohomeErrorScreen', }, /** - * Show password changed screen. + * Show the unrecoverable cryptohome error screen to ask user permission + * to collect a feedback report. */ show: function() { this.setLoading_(false); Oobe.getInstance().headerHidden = true; Oobe.showScreen({id: SCREEN_UNRECOVERABLE_CRYPTOHOME_ERROR}); + }, + + /** + * Shows the loading UI after the feedback UI is dismissed. + */ + resumeAfterFeedbackUI: function() { + $('oobe').hidden = false; } }; }); diff --git a/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.css b/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.css index f08ddb4..4bc35e3 100644 --- a/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.css +++ b/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.css @@ -4,5 +4,16 @@ */ :host .content { - padding: 1em; + padding: 24px 24px 16px; +} + +:host .title { + font-weight: bold; + white-space: nowrap; + word-wrap: normal; +} + +:host .message { + margin-bottom: 25px; + margin-top: 20px; } diff --git a/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.html b/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.html index 3c09687..bc00a60 100644 --- a/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.html +++ b/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.html @@ -3,7 +3,6 @@ found in the LICENSE file. --> <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html"> <link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html"> <!-- @@ -12,9 +11,6 @@ sending us a feedback and allows user to re-create the cryptohome so that the device could still be used. - Attributes: - 'shouldSendFeedback' - Whether to send feedback - Events: 'done' - fired when user clicks on continue button. --> @@ -23,15 +19,11 @@ <template> <div class="content"> - <div class="gaia-body-text horizontal layout center"> - <p i18n-content="unrecoverableCryptohomeErrorMessage" class="flex"> - </p> + <div i18n-content="unrecoverableCryptohomeErrorMessageTitle" class="title"> + </div> + <div class="message" + i18n-values=".innerHTML:unrecoverableCryptohomeErrorMessage"> </div> - <p> - <paper-checkbox id="sendFeedback" checked="{{shouldSendFeedback}}"> - <span i18n-content="unrecoverableCryptohomeErrorSendFeedback"></span> - </paper-checkbox> - </p> <div class="horizontal-reverse layout justified center"> <gaia-button on-tap="onContinueClicked_" i18n-content="unrecoverableCryptohomeErrorContinue"> diff --git a/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.js b/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.js index 4fd4839..4a35d7a 100644 --- a/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.js +++ b/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.js @@ -5,14 +5,7 @@ Polymer({ is: 'unrecoverable-cryptohome-error-card', - properties: { - shouldSendFeedback: { - type: Boolean, - value: true - } - }, - onContinueClicked_: function() { - this.fire('done', {shouldSendFeedback: this.shouldSendFeedback}); + this.fire('done'); }, }); diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc index e1558da..6e05725 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc @@ -29,7 +29,6 @@ #include "chrome/browser/browser_shutdown.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" -#include "chrome/browser/chromeos/feedback_util.h" #include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/login/error_screens_histogram_helper.h" #include "chrome/browser/chromeos/login/hwid_checker.h" @@ -40,6 +39,7 @@ #include "chrome/browser/chromeos/login/startup_utils.h" #include "chrome/browser/chromeos/login/ui/login_display_host.h" #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" +#include "chrome/browser/chromeos/login/ui/login_feedback.h" #include "chrome/browser/chromeos/login/ui/webui_login_display.h" #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h" #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h" @@ -451,12 +451,14 @@ void SigninScreenHandler::DeclareLocalizedValues( builder->Add("insecureURLEnrollmentError", IDS_ENTERPRISE_ENROLLMENT_AUTH_INSECURE_URL_ERROR); + builder->Add("unrecoverableCryptohomeErrorMessageTitle", + IDS_LOGIN_UNRECOVERABLE_CRYPTOHOME_ERROR_TITLE); builder->Add("unrecoverableCryptohomeErrorMessage", IDS_LOGIN_UNRECOVERABLE_CRYPTOHOME_ERROR_MESSAGE); builder->Add("unrecoverableCryptohomeErrorContinue", IDS_LOGIN_UNRECOVERABLE_CRYPTOHOME_ERROR_CONTINUE); - builder->Add("unrecoverableCryptohomeErrorSendFeedback", - IDS_LOGIN_UNRECOVERABLE_CRYPTOHOME_ERROR_SEND_FEEDBACK); + builder->Add("unrecoverableCryptohomeErrorRecreatingProfile", + IDS_LOGIN_UNRECOVERABLE_CRYPTOHOME_ERROR_WAIT_MESSAGE); } void SigninScreenHandler::RegisterMessages() { @@ -1314,10 +1316,11 @@ void SigninScreenHandler::HandleSendFeedbackAndResyncUserData() { "Auto generated feedback for http://crbug.com/547857.\n" "(uniquifier:%s)", base::Int64ToString(base::Time::Now().ToInternalValue()).c_str()); - feedback_util::SendSysLogFeedback( - Profile::FromWebUI(web_ui()), description, - base::Bind(&SigninScreenHandler::OnSysLogFeedbackSent, - weak_factory_.GetWeakPtr())); + + login_feedback_.reset(new LoginFeedback(Profile::FromWebUI(web_ui()))); + login_feedback_->Request(description, + base::Bind(&SigninScreenHandler::OnFeedbackFinished, + weak_factory_.GetWeakPtr())); } bool SigninScreenHandler::AllWhitelistedUsersPresent() { @@ -1407,8 +1410,9 @@ void SigninScreenHandler::OnCapsLockChanged(bool enabled) { CallJS("login.AccountPickerScreen.setCapsLockState", caps_lock_enabled_); } -void SigninScreenHandler::OnSysLogFeedbackSent(bool sent) { - LOG_IF(ERROR, !sent) << "Failed to send syslog feedback."; +void SigninScreenHandler::OnFeedbackFinished() { + CallJS("login.UnrecoverableCryptohomeErrorScreen.resumeAfterFeedbackUI"); + // Recreate user's cryptohome after the feedkback is attempted. HandleResyncUserData(); } diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h index dab27aa..41d4ac2 100644 --- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h @@ -49,6 +49,7 @@ class CaptivePortalWindowProxy; class CoreOobeActor; class ErrorScreensHistogramHelper; class GaiaScreenHandler; +class LoginFeedback; class NativeWindowDelegate; class SupervisedUserCreationScreenHandler; class User; @@ -412,8 +413,8 @@ class SigninScreenHandler // Returns OobeUI object of NULL. OobeUI* GetOobeUI() const; - // Callback invoked after the syslog feedback is sent. - void OnSysLogFeedbackSent(bool sent); + // Callback invoked after the feedback is finished. + void OnFeedbackFinished(); // Current UI state of the signin screen. UIState ui_state_ = UI_STATE_UNKNOWN; @@ -482,6 +483,8 @@ class SigninScreenHandler scoped_ptr<ErrorScreensHistogramHelper> histogram_helper_; + scoped_ptr<LoginFeedback> login_feedback_; + base::WeakPtrFactory<SigninScreenHandler> weak_factory_; DISALLOW_COPY_AND_ASSIGN(SigninScreenHandler); diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index 63b9df3..fc4fe14 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi @@ -127,8 +127,6 @@ 'browser/chromeos/display/output_protection_delegate.h', 'browser/chromeos/display/overscan_calibrator.cc', 'browser/chromeos/display/overscan_calibrator.h', - 'browser/chromeos/policy/display_rotation_default_handler.cc', - 'browser/chromeos/policy/display_rotation_default_handler.h', 'browser/chromeos/drive/debug_info_collector.cc', 'browser/chromeos/drive/debug_info_collector.h', 'browser/chromeos/drive/download_handler.cc', @@ -633,10 +631,12 @@ 'browser/chromeos/login/ui/lock_window_aura.h', 'browser/chromeos/login/ui/login_display.cc', 'browser/chromeos/login/ui/login_display.h', - 'browser/chromeos/login/ui/login_display_host.h', 'browser/chromeos/login/ui/login_display_host.cc', + 'browser/chromeos/login/ui/login_display_host.h', 'browser/chromeos/login/ui/login_display_host_impl.cc', 'browser/chromeos/login/ui/login_display_host_impl.h', + 'browser/chromeos/login/ui/login_feedback.cc', + 'browser/chromeos/login/ui/login_feedback.h', 'browser/chromeos/login/ui/login_web_dialog.cc', 'browser/chromeos/login/ui/login_web_dialog.h', 'browser/chromeos/login/ui/models/user_board_model.cc', @@ -664,12 +664,12 @@ 'browser/chromeos/login/users/avatar/user_image_manager_impl.h', 'browser/chromeos/login/users/avatar/user_image_sync_observer.cc', 'browser/chromeos/login/users/avatar/user_image_sync_observer.h', - 'browser/chromeos/login/users/chrome_user_manager_util.cc', - 'browser/chromeos/login/users/chrome_user_manager_util.h', 'browser/chromeos/login/users/chrome_user_manager.cc', 'browser/chromeos/login/users/chrome_user_manager.h', 'browser/chromeos/login/users/chrome_user_manager_impl.cc', 'browser/chromeos/login/users/chrome_user_manager_impl.h', + 'browser/chromeos/login/users/chrome_user_manager_util.cc', + 'browser/chromeos/login/users/chrome_user_manager_util.h', 'browser/chromeos/login/users/default_user_image/default_user_images.cc', 'browser/chromeos/login/users/default_user_image/default_user_images.h', 'browser/chromeos/login/users/multi_profile_user_controller.cc', @@ -807,6 +807,8 @@ 'browser/chromeos/policy/device_policy_decoder_chromeos.h', 'browser/chromeos/policy/device_status_collector.cc', 'browser/chromeos/policy/device_status_collector.h', + 'browser/chromeos/policy/display_rotation_default_handler.cc', + 'browser/chromeos/policy/display_rotation_default_handler.h', 'browser/chromeos/policy/enrollment_config.cc', 'browser/chromeos/policy/enrollment_config.h', 'browser/chromeos/policy/enrollment_handler_chromeos.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 6b43e23..049c723 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -783,6 +783,7 @@ 'browser/chromeos/login/test/wizard_in_process_browser_test.cc', 'browser/chromeos/login/test/wizard_in_process_browser_test.h', 'browser/chromeos/login/ui/captive_portal_window_browsertest.cc', + 'browser/chromeos/login/ui/login_feedback_browsertest.cc', 'browser/chromeos/login/ui/login_web_dialog_browsertest.cc', 'browser/chromeos/login/ui/simple_web_view_dialog_browsertest.cc', 'browser/chromeos/login/ui/user_adding_screen_browsertest.cc', diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc index 81bc30f..c6b2bd2 100644 --- a/chrome/common/extensions/extension_constants.cc +++ b/chrome/common/extensions/extension_constants.cc @@ -37,6 +37,7 @@ const char kDriveExtensionId[] = "ghbmnnjooekpmoecnnnilnnbdlolhkhi"; const char kDriveHostedAppId[] = "apdfllckaahabafndbhieahigkjlhalf"; const char kEasyUnlockAppId[] = "mkaemigholebcgchlkbankmihknojeak"; const char kEnterpriseWebStoreAppId[] = "afchcafgojfnemjkcbhfekplkmjaldaa"; +const char kFeedbackExtensionId[] = "gfdkimpbcpahaombhbimeihdjnejgicl"; const char kGmailAppId[] = "pjkljhegncpnkpknbcohdijeoejaedia"; const char kGoogleDocAppId[] = "aohghmighlieiainnegkcijnfilokake"; const char kGooglePlayMusicAppId[] = "icppfcnhkcmnfdhfhphakoifcfokfdhg"; diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h index 5fe6cec..a771282 100644 --- a/chrome/common/extensions/extension_constants.h +++ b/chrome/common/extensions/extension_constants.h @@ -55,6 +55,9 @@ extern const char kEasyUnlockAppId[]; // The extension id of the Enterprise Web Store component application. extern const char kEnterpriseWebStoreAppId[]; +// The extension id of the feedback component extension. +extern const char kFeedbackExtensionId[]; + // The extension id of GMail application. extern const char kGmailAppId[]; |
