Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(18)

Side by Side Diff: chrome/browser/chromeos/login/ui/login_feedback.cc

Issue 2837613002: cros: Fix race on feedback extension loading (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/login/ui/login_feedback.h" 5 #include "chrome/browser/chromeos/login/ui/login_feedback.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/threading/thread_task_runner_handle.h"
11 #include "base/time/time.h" 12 #include "base/time/time.h"
12 #include "chrome/browser/chromeos/login/ui/login_display_host.h" 13 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
13 #include "chrome/browser/extensions/api/feedback_private/feedback_private_api.h" 14 #include "chrome/browser/extensions/api/feedback_private/feedback_private_api.h"
14 #include "chrome/browser/extensions/component_loader.h" 15 #include "chrome/browser/extensions/component_loader.h"
15 #include "chrome/browser/extensions/extension_service.h" 16 #include "chrome/browser/extensions/extension_service.h"
16 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/common/extensions/extension_constants.h" 18 #include "chrome/common/extensions/extension_constants.h"
18 #include "chrome/grit/browser_resources.h" 19 #include "chrome/grit/browser_resources.h"
19 #include "content/public/browser/browser_thread.h" 20 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/web_contents.h"
20 #include "content/public/browser/web_contents_observer.h" 22 #include "content/public/browser/web_contents_observer.h"
21 #include "extensions/browser/app_window/app_window.h" 23 #include "extensions/browser/app_window/app_window.h"
22 #include "extensions/browser/app_window/app_window_registry.h" 24 #include "extensions/browser/app_window/app_window_registry.h"
23 #include "extensions/browser/extension_host.h" 25 #include "extensions/browser/extension_host.h"
24 #include "extensions/browser/extension_system.h" 26 #include "extensions/browser/extension_system.h"
25 #include "extensions/browser/process_manager.h" 27 #include "extensions/browser/process_manager.h"
26 #include "extensions/browser/process_manager_observer.h" 28 #include "extensions/browser/process_manager_observer.h"
27 #include "extensions/common/extension.h" 29 #include "extensions/common/extension.h"
28 #include "ui/aura/window.h" 30 #include "ui/aura/window.h"
29 #include "ui/views/widget/widget.h" 31 #include "ui/views/widget/widget.h"
(...skipping 23 matching lines...) Expand all
53 public content::WebContentsObserver { 55 public content::WebContentsObserver {
54 public: 56 public:
55 // Loads the feedback extension on the given profile and invokes 57 // Loads the feedback extension on the given profile and invokes
56 // |on_ready_callback| when it is ready. 58 // |on_ready_callback| when it is ready.
57 static void Load(Profile* profile, const base::Closure& on_ready_callback); 59 static void Load(Profile* profile, const base::Closure& on_ready_callback);
58 60
59 private: 61 private:
60 explicit FeedbackExtensionLoader(Profile* profile); 62 explicit FeedbackExtensionLoader(Profile* profile);
61 ~FeedbackExtensionLoader() override; 63 ~FeedbackExtensionLoader() override;
62 64
65 void Initialize();
66
63 void AddOnReadyCallback(const base::Closure& on_ready_callback); 67 void AddOnReadyCallback(const base::Closure& on_ready_callback);
64 void RunOnReadyCallbacks(); 68 void RunOnReadyCallbacks();
65 69
66 // extensions::ProcessManagerObserver 70 // extensions::ProcessManagerObserver
67 void OnBackgroundHostCreated(extensions::ExtensionHost* host) override; 71 void OnBackgroundHostCreated(extensions::ExtensionHost* host) override;
68 void OnBackgroundHostClose(const std::string& extension_id) override; 72 void OnBackgroundHostClose(const std::string& extension_id) override;
69 73
70 // content::WebContentsObserver 74 // content::WebContentsObserver
71 void DocumentOnLoadCompletedInMainFrame() override; 75 void DocumentOnLoadCompletedInMainFrame() override;
72 76
73 Profile* const profile_; 77 Profile* const profile_;
74 std::vector<base::Closure> on_ready_callbacks_; 78 std::vector<base::Closure> on_ready_callbacks_;
75 bool ready_ = false; 79 bool ready_ = false;
76 80
77 DISALLOW_COPY_AND_ASSIGN(FeedbackExtensionLoader); 81 DISALLOW_COPY_AND_ASSIGN(FeedbackExtensionLoader);
78 }; 82 };
79 83
80 // Current live instance of FeedbackExtensionLoader. 84 // Current live instance of FeedbackExtensionLoader.
81 FeedbackExtensionLoader* instance = nullptr; 85 FeedbackExtensionLoader* instance = nullptr;
82 86
83 // static 87 // static
84 void FeedbackExtensionLoader::Load(Profile* profile, 88 void FeedbackExtensionLoader::Load(Profile* profile,
85 const base::Closure& on_ready_callback) { 89 const base::Closure& on_ready_callback) {
86 if (instance == nullptr) 90 if (instance == nullptr) {
87 instance = new FeedbackExtensionLoader(profile); 91 instance = new FeedbackExtensionLoader(profile);
92 instance->Initialize();
93 }
88 94
89 DCHECK_EQ(instance->profile_, profile); 95 DCHECK_EQ(instance->profile_, profile);
90 DCHECK(!on_ready_callback.is_null()); 96 DCHECK(!on_ready_callback.is_null());
91 instance->AddOnReadyCallback(on_ready_callback); 97 instance->AddOnReadyCallback(on_ready_callback);
92 } 98 }
93 99
94 FeedbackExtensionLoader::FeedbackExtensionLoader(Profile* profile) 100 FeedbackExtensionLoader::FeedbackExtensionLoader(Profile* profile)
95 : profile_(profile) { 101 : profile_(profile) {}
96 extensions::ComponentLoader* component_loader = GetComponentLoader(profile_);
97 DCHECK(!component_loader->Exists(extension_misc::kFeedbackExtensionId))
98 << "Feedback extension should not be loaded in signin profile by default";
99 component_loader->Add(IDR_FEEDBACK_MANIFEST,
100 base::FilePath(FILE_PATH_LITERAL("feedback")));
101
102 extensions::ProcessManager* pm = GetProcessManager(profile_);
103 pm->AddObserver(this);
104 DCHECK(
105 !pm->GetBackgroundHostForExtension(extension_misc::kFeedbackExtensionId));
106 }
107 102
108 FeedbackExtensionLoader::~FeedbackExtensionLoader() { 103 FeedbackExtensionLoader::~FeedbackExtensionLoader() {
109 DCHECK_EQ(instance, this); 104 DCHECK_EQ(instance, this);
110 instance = nullptr; 105 instance = nullptr;
111 106
112 GetProcessManager(profile_)->RemoveObserver(this); 107 GetProcessManager(profile_)->RemoveObserver(this);
113 GetComponentLoader(profile_)->Remove(extension_misc::kFeedbackExtensionId); 108 GetComponentLoader(profile_)->Remove(extension_misc::kFeedbackExtensionId);
114 } 109 }
115 110
111 void FeedbackExtensionLoader::Initialize() {
112 extensions::ProcessManager* pm = GetProcessManager(profile_);
113 pm->AddObserver(this);
114 extensions::ExtensionHost* const host =
115 pm->GetBackgroundHostForExtension(extension_misc::kFeedbackExtensionId);
116 if (host) {
117 OnBackgroundHostCreated(host);
118 if (!host->host_contents()->IsLoading())
119 DocumentOnLoadCompletedInMainFrame();
120 return;
121 }
122
123 extensions::ComponentLoader* component_loader = GetComponentLoader(profile_);
124 if (!component_loader->Exists(extension_misc::kFeedbackExtensionId)) {
125 component_loader->Add(IDR_FEEDBACK_MANIFEST,
126 base::FilePath(FILE_PATH_LITERAL("feedback")));
127 }
128 }
129
116 void FeedbackExtensionLoader::AddOnReadyCallback( 130 void FeedbackExtensionLoader::AddOnReadyCallback(
117 const base::Closure& on_ready_callback) { 131 const base::Closure& on_ready_callback) {
118 on_ready_callbacks_.push_back(on_ready_callback); 132 on_ready_callbacks_.push_back(on_ready_callback);
119 if (ready_) 133 if (ready_)
120 RunOnReadyCallbacks(); 134 RunOnReadyCallbacks();
121 } 135 }
122 136
123 void FeedbackExtensionLoader::RunOnReadyCallbacks() { 137 void FeedbackExtensionLoader::RunOnReadyCallbacks() {
124 std::vector<base::Closure> callbacks; 138 std::vector<base::Closure> callbacks;
125 callbacks.swap(on_ready_callbacks_); 139 callbacks.swap(on_ready_callbacks_);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 void LoginFeedback::EnsureFeedbackUI() { 248 void LoginFeedback::EnsureFeedbackUI() {
235 // Bail if any feedback app window is opened. 249 // Bail if any feedback app window is opened.
236 if (feedback_window_handler_->HasFeedbackAppWindow()) 250 if (feedback_window_handler_->HasFeedbackAppWindow())
237 return; 251 return;
238 252
239 extensions::FeedbackPrivateAPI* api = 253 extensions::FeedbackPrivateAPI* api =
240 extensions::FeedbackPrivateAPI::GetFactoryInstance()->Get(profile_); 254 extensions::FeedbackPrivateAPI::GetFactoryInstance()->Get(profile_);
241 api->RequestFeedbackForFlow( 255 api->RequestFeedbackForFlow(
242 description_, "Login", GURL(), 256 description_, "Login", GURL(),
243 extensions::api::feedback_private::FeedbackFlow::FEEDBACK_FLOW_LOGIN); 257 extensions::api::feedback_private::FeedbackFlow::FEEDBACK_FLOW_LOGIN);
258
259 // Make sure there is a feedback app window opened.
260 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
261 FROM_HERE,
262 base::Bind(&LoginFeedback::EnsureFeedbackUI, weak_factory_.GetWeakPtr()),
263 base::TimeDelta::FromSeconds(1));
244 } 264 }
245 265
246 void LoginFeedback::OnFeedbackFinished() { 266 void LoginFeedback::OnFeedbackFinished() {
247 if (!finished_callback_.is_null()) 267 if (!finished_callback_.is_null())
248 finished_callback_.Run(); 268 finished_callback_.Run();
249 } 269 }
250 270
251 } // namespace chromeos 271 } // namespace chromeos
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698