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

Side by Side Diff: chrome/browser/chromeos/note_taking_helper.cc

Issue 2587913006: chromeos: Notify about Chrome note-taking apps. (Closed)
Patch Set: work around profile lifecycle wonkiness in browser tests Created 4 years 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
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/note_taking_helper.h" 5 #include "chrome/browser/chromeos/note_taking_helper.h"
6 6
7 #include <algorithm>
7 #include <utility> 8 #include <utility>
8 9
9 #include "apps/launcher.h" 10 #include "apps/launcher.h"
10 #include "ash/common/system/chromeos/palette/palette_utils.h" 11 #include "ash/common/system/chromeos/palette/palette_utils.h"
11 #include "base/bind.h" 12 #include "base/bind.h"
12 #include "base/command_line.h" 13 #include "base/command_line.h"
13 #include "base/files/file_path.h" 14 #include "base/files/file_path.h"
14 #include "base/logging.h" 15 #include "base/logging.h"
15 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
16 #include "base/memory/ref_counted.h" 17 #include "base/memory/ref_counted.h"
17 #include "base/strings/string_split.h" 18 #include "base/strings/string_split.h"
19 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/chrome_notification_types.h"
18 #include "chrome/browser/chromeos/file_manager/path_util.h" 21 #include "chrome/browser/chromeos/file_manager/path_util.h"
19 #include "chrome/browser/profiles/profile.h" 22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/profiles/profile_manager.h"
20 #include "chrome/common/pref_names.h" 24 #include "chrome/common/pref_names.h"
21 #include "chromeos/chromeos_switches.h" 25 #include "chromeos/chromeos_switches.h"
22 #include "components/arc/arc_bridge_service.h" 26 #include "components/arc/arc_bridge_service.h"
23 #include "components/arc/common/intent_helper.mojom.h" 27 #include "components/arc/common/intent_helper.mojom.h"
24 #include "components/prefs/pref_service.h" 28 #include "components/prefs/pref_service.h"
25 #include "content/public/browser/browser_thread.h" 29 #include "content/public/browser/browser_thread.h"
30 #include "content/public/browser/notification_service.h"
26 #include "extensions/browser/extension_registry.h" 31 #include "extensions/browser/extension_registry.h"
27 #include "extensions/common/api/app_runtime.h" 32 #include "extensions/common/api/app_runtime.h"
28 #include "extensions/common/extension.h" 33 #include "extensions/common/extension.h"
29 #include "url/gurl.h" 34 #include "url/gurl.h"
30 35
31 namespace app_runtime = extensions::api::app_runtime; 36 namespace app_runtime = extensions::api::app_runtime;
32 37
33 namespace chromeos { 38 namespace chromeos {
34 namespace { 39 namespace {
35 40
(...skipping 29 matching lines...) Expand all
65 // Creates a new Mojo IntentInfo struct for launching an Android note-taking app 70 // Creates a new Mojo IntentInfo struct for launching an Android note-taking app
66 // with an optional ClipData URI. 71 // with an optional ClipData URI.
67 arc::mojom::IntentInfoPtr CreateIntentInfo(const GURL& clip_data_uri) { 72 arc::mojom::IntentInfoPtr CreateIntentInfo(const GURL& clip_data_uri) {
68 arc::mojom::IntentInfoPtr intent = arc::mojom::IntentInfo::New(); 73 arc::mojom::IntentInfoPtr intent = arc::mojom::IntentInfo::New();
69 intent->action = NoteTakingHelper::kIntentAction; 74 intent->action = NoteTakingHelper::kIntentAction;
70 if (!clip_data_uri.is_empty()) 75 if (!clip_data_uri.is_empty())
71 intent->clip_data_uri = clip_data_uri.spec(); 76 intent->clip_data_uri = clip_data_uri.spec();
72 return intent; 77 return intent;
73 } 78 }
74 79
75 // Returns all installed and enabled whitelisted Chrome note-taking apps.
76 std::vector<const extensions::Extension*> GetChromeApps(Profile* profile) {
77 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
78 // TODO(derat): Query for additional Chrome apps once http://crbug.com/657139
79 // is resolved.
80 std::vector<extensions::ExtensionId> ids;
81 const std::string switch_value =
82 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
83 switches::kNoteTakingAppIds);
84 if (!switch_value.empty()) {
85 ids = base::SplitString(switch_value, ",", base::TRIM_WHITESPACE,
86 base::SPLIT_WANT_NONEMPTY);
87 }
88 ids.insert(ids.end(), kExtensionIds,
89 kExtensionIds + arraysize(kExtensionIds));
90
91 const extensions::ExtensionRegistry* extension_registry =
92 extensions::ExtensionRegistry::Get(profile);
93 const extensions::ExtensionSet& enabled_extensions =
94 extension_registry->enabled_extensions();
95
96 std::vector<const extensions::Extension*> extensions;
97 for (const auto& id : ids) {
98 if (enabled_extensions.Contains(id)) {
99 extensions.push_back(extension_registry->GetExtensionById(
100 id, extensions::ExtensionRegistry::ENABLED));
101 }
102 }
103 return extensions;
104 }
105
106 } // namespace 80 } // namespace
107 81
108 const char NoteTakingHelper::kIntentAction[] = 82 const char NoteTakingHelper::kIntentAction[] =
109 "org.chromium.arc.intent.action.CREATE_NOTE"; 83 "org.chromium.arc.intent.action.CREATE_NOTE";
110 const char NoteTakingHelper::kDevKeepExtensionId[] = 84 const char NoteTakingHelper::kDevKeepExtensionId[] =
111 "ogfjaccbdfhecploibfbhighmebiffla"; 85 "ogfjaccbdfhecploibfbhighmebiffla";
112 const char NoteTakingHelper::kProdKeepExtensionId[] = 86 const char NoteTakingHelper::kProdKeepExtensionId[] =
113 "hmjkmjkepdijhoojdojkdfohbdgmmhki"; 87 "hmjkmjkepdijhoojdojkdfohbdgmmhki";
114 88
115 // static 89 // static
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 for (auto& observer : observers_) 188 for (auto& observer : observers_)
215 observer.OnAvailableNoteTakingAppsUpdated(); 189 observer.OnAvailableNoteTakingAppsUpdated();
216 } 190 }
217 191
218 NoteTakingHelper::NoteTakingHelper() 192 NoteTakingHelper::NoteTakingHelper()
219 : launch_chrome_app_callback_( 193 : launch_chrome_app_callback_(
220 base::Bind(&apps::LaunchPlatformAppWithAction)), 194 base::Bind(&apps::LaunchPlatformAppWithAction)),
221 weak_ptr_factory_(this) { 195 weak_ptr_factory_(this) {
222 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 196 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
223 197
198 const std::string switch_value =
199 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
200 switches::kNoteTakingAppIds);
201 if (!switch_value.empty()) {
202 whitelisted_chrome_app_ids_ = base::SplitString(
203 switch_value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
204 }
205 whitelisted_chrome_app_ids_.insert(whitelisted_chrome_app_ids_.end(),
206 kExtensionIds,
207 kExtensionIds + arraysize(kExtensionIds));
208
209 // Track profiles so we can observe their extension registries.
210 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED,
211 content::NotificationService::AllBrowserContextsAndSources());
212 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
213 content::NotificationService::AllBrowserContextsAndSources());
214 for (Profile* profile :
215 g_browser_process->profile_manager()->GetLoadedProfiles()) {
216 AddProfile(profile);
217 }
218
224 // Check if the primary profile has already enabled ARC and watch for changes. 219 // Check if the primary profile has already enabled ARC and watch for changes.
225 auto session_manager = arc::ArcSessionManager::Get(); 220 auto session_manager = arc::ArcSessionManager::Get();
226 session_manager->AddObserver(this); 221 session_manager->AddObserver(this);
227 android_enabled_ = session_manager->IsArcEnabled(); 222 android_enabled_ = session_manager->IsArcEnabled();
228 223
229 // ArcServiceManager will notify us about changes to the list of available 224 // ArcServiceManager will notify us about changes to the list of available
230 // Android apps. 225 // Android apps.
231 auto service_manager = arc::ArcServiceManager::Get(); 226 auto service_manager = arc::ArcServiceManager::Get();
232 service_manager->AddObserver(this); 227 service_manager->AddObserver(this);
233 228
234 // If the ARC intent helper is ready, get the Android apps. Otherwise, 229 // If the ARC intent helper is ready, get the Android apps. Otherwise,
235 // UpdateAndroidApps() will be called when ArcServiceManager calls 230 // UpdateAndroidApps() will be called when ArcServiceManager calls
236 // OnIntentFiltersUpdated(). 231 // OnIntentFiltersUpdated().
237 if (android_enabled_ && 232 if (android_enabled_ &&
238 arc::ArcServiceManager::Get() 233 arc::ArcServiceManager::Get()
239 ->arc_bridge_service() 234 ->arc_bridge_service()
240 ->intent_helper() 235 ->intent_helper()
241 ->has_instance()) 236 ->has_instance())
242 UpdateAndroidApps(); 237 UpdateAndroidApps();
243 } 238 }
244 239
245 NoteTakingHelper::~NoteTakingHelper() { 240 NoteTakingHelper::~NoteTakingHelper() {
246 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 241 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
242 while (!profiles_.empty())
243 RemoveProfile(*profiles_.begin());
244
247 // ArcSessionManagerTest shuts down ARC before NoteTakingHelper. 245 // ArcSessionManagerTest shuts down ARC before NoteTakingHelper.
248 if (arc::ArcServiceManager::Get()) 246 if (arc::ArcServiceManager::Get())
249 arc::ArcServiceManager::Get()->RemoveObserver(this); 247 arc::ArcServiceManager::Get()->RemoveObserver(this);
250 if (arc::ArcSessionManager::Get()) 248 if (arc::ArcSessionManager::Get())
251 arc::ArcSessionManager::Get()->RemoveObserver(this); 249 arc::ArcSessionManager::Get()->RemoveObserver(this);
252 } 250 }
253 251
252 bool NoteTakingHelper::IsWhitelistedChromeApp(
253 const extensions::Extension* extension) const {
254 DCHECK(extension);
255 return std::find(whitelisted_chrome_app_ids_.begin(),
256 whitelisted_chrome_app_ids_.end(),
257 extension->id()) != whitelisted_chrome_app_ids_.end();
258 }
259
260 void NoteTakingHelper::AddProfile(Profile* profile) {
261 DCHECK(profile);
262 CHECK(!profiles_.count(profile));
263 profiles_.insert(profile);
264 extensions::ExtensionRegistry::Get(profile)->AddObserver(this);
xiyuan 2016/12/21 16:46:51 Suggest to use base::ScopedObserver. It can track
Daniel Erat 2016/12/21 17:04:53 thanks, i'd forgotten about ScopedObserver and add
265 }
266
267 void NoteTakingHelper::RemoveProfile(Profile* profile) {
268 DCHECK(profile);
269 // Some browser tests appear to destroy profiles before fully initializing
270 // them, resulting in NOTIFICATION_PROFILE_DESTROYED being sent without an
271 // earlier NOTIFICATION_PROFILE_ADDED.
272 if (profiles_.count(profile)) {
273 profiles_.erase(profile);
274 extensions::ExtensionRegistry::Get(profile)->RemoveObserver(this);
275 }
276 }
277
278 std::vector<const extensions::Extension*> NoteTakingHelper::GetChromeApps(
279 Profile* profile) const {
280 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
281 const extensions::ExtensionRegistry* extension_registry =
282 extensions::ExtensionRegistry::Get(profile);
283 const extensions::ExtensionSet& enabled_extensions =
284 extension_registry->enabled_extensions();
285
286 // TODO(derat): Query for additional Chrome apps once http://crbug.com/657139
287 // is resolved.
288 std::vector<const extensions::Extension*> extensions;
289 for (const auto& id : whitelisted_chrome_app_ids_) {
290 if (enabled_extensions.Contains(id)) {
291 extensions.push_back(extension_registry->GetExtensionById(
292 id, extensions::ExtensionRegistry::ENABLED));
293 }
294 }
295 return extensions;
296 }
297
254 void NoteTakingHelper::UpdateAndroidApps() { 298 void NoteTakingHelper::UpdateAndroidApps() {
255 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 299 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
256 auto* helper = GetIntentHelper("RequestIntentHandlerList", 12); 300 auto* helper = GetIntentHelper("RequestIntentHandlerList", 12);
257 if (!helper) 301 if (!helper)
258 return; 302 return;
259 helper->RequestIntentHandlerList( 303 helper->RequestIntentHandlerList(
260 CreateIntentInfo(GURL()), base::Bind(&NoteTakingHelper::OnGotAndroidApps, 304 CreateIntentInfo(GURL()), base::Bind(&NoteTakingHelper::OnGotAndroidApps,
261 weak_ptr_factory_.GetWeakPtr())); 305 weak_ptr_factory_.GetWeakPtr()));
262 } 306 }
263 307
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 return false; 364 return false;
321 } 365 }
322 auto action_data = base::MakeUnique<app_runtime::ActionData>(); 366 auto action_data = base::MakeUnique<app_runtime::ActionData>();
323 action_data->action_type = app_runtime::ActionType::ACTION_TYPE_NEW_NOTE; 367 action_data->action_type = app_runtime::ActionType::ACTION_TYPE_NEW_NOTE;
324 launch_chrome_app_callback_.Run(profile, app, std::move(action_data), path); 368 launch_chrome_app_callback_.Run(profile, app, std::move(action_data), path);
325 } 369 }
326 370
327 return true; 371 return true;
328 } 372 }
329 373
374 void NoteTakingHelper::Observe(int type,
375 const content::NotificationSource& source,
376 const content::NotificationDetails& details) {
377 switch (type) {
378 case chrome::NOTIFICATION_PROFILE_ADDED:
379 AddProfile(content::Source<Profile>(source).ptr());
380 break;
381 case chrome::NOTIFICATION_PROFILE_DESTROYED:
382 RemoveProfile(content::Source<Profile>(source).ptr());
383 break;
384 default:
385 NOTREACHED();
386 }
387 }
388
389 void NoteTakingHelper::OnExtensionLoaded(
390 content::BrowserContext* browser_context,
391 const extensions::Extension* extension) {
392 if (IsWhitelistedChromeApp(extension)) {
393 for (auto& observer : observers_)
394 observer.OnAvailableNoteTakingAppsUpdated();
395 }
396 }
397
398 void NoteTakingHelper::OnExtensionUnloaded(
399 content::BrowserContext* browser_context,
400 const extensions::Extension* extension,
401 extensions::UnloadedExtensionInfo::Reason reason) {
402 if (IsWhitelistedChromeApp(extension)) {
403 for (auto& observer : observers_)
404 observer.OnAvailableNoteTakingAppsUpdated();
405 }
406 }
407
330 } // namespace chromeos 408 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/note_taking_helper.h ('k') | chrome/browser/chromeos/note_taking_helper_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698