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

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

Issue 2587913006: chromeos: Notify about Chrome note-taking apps. (Closed)
Patch Set: use ScopedObserver Created 3 years, 12 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
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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 android_apps_.clear(); 185 android_apps_.clear();
212 android_apps_received_ = false; 186 android_apps_received_ = false;
213 } 187 }
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)),
195 extension_registry_observer_(this),
221 weak_ptr_factory_(this) { 196 weak_ptr_factory_(this) {
222 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 197 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
223 198
199 const std::string switch_value =
200 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
201 switches::kNoteTakingAppIds);
202 if (!switch_value.empty()) {
203 whitelisted_chrome_app_ids_ = base::SplitString(
204 switch_value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
205 }
206 whitelisted_chrome_app_ids_.insert(whitelisted_chrome_app_ids_.end(),
207 kExtensionIds,
208 kExtensionIds + arraysize(kExtensionIds));
209
210 // Track profiles so we can observe their extension registries.
211 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED,
212 content::NotificationService::AllBrowserContextsAndSources());
213 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
214 content::NotificationService::AllBrowserContextsAndSources());
215 for (Profile* profile :
216 g_browser_process->profile_manager()->GetLoadedProfiles()) {
217 extension_registry_observer_.Add(
218 extensions::ExtensionRegistry::Get(profile));
219 }
220
224 // Check if the primary profile has already enabled ARC and watch for changes. 221 // Check if the primary profile has already enabled ARC and watch for changes.
225 auto session_manager = arc::ArcSessionManager::Get(); 222 auto session_manager = arc::ArcSessionManager::Get();
226 session_manager->AddObserver(this); 223 session_manager->AddObserver(this);
227 android_enabled_ = session_manager->IsArcEnabled(); 224 android_enabled_ = session_manager->IsArcEnabled();
228 225
229 // ArcServiceManager will notify us about changes to the list of available 226 // ArcServiceManager will notify us about changes to the list of available
230 // Android apps. 227 // Android apps.
231 auto service_manager = arc::ArcServiceManager::Get(); 228 auto service_manager = arc::ArcServiceManager::Get();
232 service_manager->AddObserver(this); 229 service_manager->AddObserver(this);
233 230
234 // If the ARC intent helper is ready, get the Android apps. Otherwise, 231 // If the ARC intent helper is ready, get the Android apps. Otherwise,
235 // UpdateAndroidApps() will be called when ArcServiceManager calls 232 // UpdateAndroidApps() will be called when ArcServiceManager calls
236 // OnIntentFiltersUpdated(). 233 // OnIntentFiltersUpdated().
237 if (android_enabled_ && 234 if (android_enabled_ &&
238 arc::ArcServiceManager::Get() 235 arc::ArcServiceManager::Get()
239 ->arc_bridge_service() 236 ->arc_bridge_service()
240 ->intent_helper() 237 ->intent_helper()
241 ->has_instance()) 238 ->has_instance())
242 UpdateAndroidApps(); 239 UpdateAndroidApps();
243 } 240 }
244 241
245 NoteTakingHelper::~NoteTakingHelper() { 242 NoteTakingHelper::~NoteTakingHelper() {
246 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 243 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
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 std::vector<const extensions::Extension*> NoteTakingHelper::GetChromeApps(
261 Profile* profile) const {
262 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
263 const extensions::ExtensionRegistry* extension_registry =
264 extensions::ExtensionRegistry::Get(profile);
265 const extensions::ExtensionSet& enabled_extensions =
266 extension_registry->enabled_extensions();
267
268 // TODO(derat): Query for additional Chrome apps once http://crbug.com/657139
269 // is resolved.
270 std::vector<const extensions::Extension*> extensions;
271 for (const auto& id : whitelisted_chrome_app_ids_) {
272 if (enabled_extensions.Contains(id)) {
273 extensions.push_back(extension_registry->GetExtensionById(
274 id, extensions::ExtensionRegistry::ENABLED));
275 }
276 }
277 return extensions;
278 }
279
254 void NoteTakingHelper::UpdateAndroidApps() { 280 void NoteTakingHelper::UpdateAndroidApps() {
255 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 281 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
256 auto* helper = GetIntentHelper("RequestIntentHandlerList", 12); 282 auto* helper = GetIntentHelper("RequestIntentHandlerList", 12);
257 if (!helper) 283 if (!helper)
258 return; 284 return;
259 helper->RequestIntentHandlerList( 285 helper->RequestIntentHandlerList(
260 CreateIntentInfo(GURL()), base::Bind(&NoteTakingHelper::OnGotAndroidApps, 286 CreateIntentInfo(GURL()), base::Bind(&NoteTakingHelper::OnGotAndroidApps,
261 weak_ptr_factory_.GetWeakPtr())); 287 weak_ptr_factory_.GetWeakPtr()));
262 } 288 }
263 289
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 return false; 346 return false;
321 } 347 }
322 auto action_data = base::MakeUnique<app_runtime::ActionData>(); 348 auto action_data = base::MakeUnique<app_runtime::ActionData>();
323 action_data->action_type = app_runtime::ActionType::ACTION_TYPE_NEW_NOTE; 349 action_data->action_type = app_runtime::ActionType::ACTION_TYPE_NEW_NOTE;
324 launch_chrome_app_callback_.Run(profile, app, std::move(action_data), path); 350 launch_chrome_app_callback_.Run(profile, app, std::move(action_data), path);
325 } 351 }
326 352
327 return true; 353 return true;
328 } 354 }
329 355
356 void NoteTakingHelper::Observe(int type,
357 const content::NotificationSource& source,
358 const content::NotificationDetails& details) {
359 switch (type) {
360 case chrome::NOTIFICATION_PROFILE_ADDED: {
361 auto registry = extensions::ExtensionRegistry::Get(
362 content::Source<Profile>(source).ptr());
363 CHECK(!extension_registry_observer_.IsObserving(registry));
xiyuan 2016/12/21 17:11:17 nit: DCHECK should be enough. NOTIFICATION_PROFILE
Daniel Erat 2016/12/21 18:08:51 thanks, makes sense! i realized that i probably h
xiyuan 2016/12/21 18:19:41 ExtensionRegistryObserver has an "OnShutdown" meth
Daniel Erat 2016/12/21 18:41:27 thanks for pointing it out; that's much cleaner.
364 extension_registry_observer_.Add(registry);
365 break;
366 }
367 case chrome::NOTIFICATION_PROFILE_DESTROYED: {
368 // Some browser tests appear to destroy profiles before fully initializing
369 // them, resulting in NOTIFICATION_PROFILE_DESTROYED being sent without an
370 // earlier NOTIFICATION_PROFILE_ADDED.
371 auto registry = extensions::ExtensionRegistry::Get(
372 content::Source<Profile>(source).ptr());
373 if (extension_registry_observer_.IsObserving(registry))
374 extension_registry_observer_.Remove(registry);
375 break;
376 }
377 default:
378 NOTREACHED();
379 }
380 }
381
382 void NoteTakingHelper::OnExtensionLoaded(
383 content::BrowserContext* browser_context,
384 const extensions::Extension* extension) {
385 if (IsWhitelistedChromeApp(extension)) {
386 for (auto& observer : observers_)
387 observer.OnAvailableNoteTakingAppsUpdated();
388 }
389 }
390
391 void NoteTakingHelper::OnExtensionUnloaded(
392 content::BrowserContext* browser_context,
393 const extensions::Extension* extension,
394 extensions::UnloadedExtensionInfo::Reason reason) {
395 if (IsWhitelistedChromeApp(extension)) {
396 for (auto& observer : observers_)
397 observer.OnAvailableNoteTakingAppsUpdated();
398 }
399 }
400
330 } // namespace chromeos 401 } // 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