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

Side by Side Diff: chrome/browser/extensions/api/messaging/message_service.cc

Issue 637463002: Revert "Remote Assistance on Chrome OS Part III - NativeMessageHost" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/extensions/api/messaging/message_service.h" 5 #include "chrome/browser/extensions/api/messaging/message_service.h"
6 6
7 #include "base/atomic_sequence_num.h" 7 #include "base/atomic_sequence_num.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/json/json_writer.h" 10 #include "base/json/json_writer.h"
11 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/stl_util.h" 13 #include "base/stl_util.h"
15 #include "base/values.h" 14 #include "base/values.h"
16 #include "chrome/browser/chrome_notification_types.h" 15 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/extensions/api/messaging/extension_message_port.h" 16 #include "chrome/browser/extensions/api/messaging/extension_message_port.h"
18 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h" 17 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h"
19 #include "chrome/browser/extensions/api/messaging/native_message_port.h" 18 #include "chrome/browser/extensions/api/messaging/native_message_port.h"
20 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" 19 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
21 #include "chrome/browser/extensions/extension_service.h" 20 #include "chrome/browser/extensions/extension_service.h"
22 #include "chrome/browser/extensions/extension_tab_util.h" 21 #include "chrome/browser/extensions/extension_tab_util.h"
23 #include "chrome/browser/extensions/extension_util.h" 22 #include "chrome/browser/extensions/extension_util.h"
24 #include "chrome/browser/profiles/profile.h" 23 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/tab_contents/tab_util.h" 24 #include "chrome/browser/tab_contents/tab_util.h"
26 #include "content/public/browser/notification_service.h" 25 #include "content/public/browser/notification_service.h"
27 #include "content/public/browser/render_process_host.h" 26 #include "content/public/browser/render_process_host.h"
28 #include "content/public/browser/render_view_host.h" 27 #include "content/public/browser/render_view_host.h"
29 #include "content/public/browser/render_widget_host.h" 28 #include "content/public/browser/render_widget_host.h"
30 #include "content/public/browser/render_widget_host_view.h" 29 #include "content/public/browser/render_widget_host_view.h"
31 #include "content/public/browser/site_instance.h" 30 #include "content/public/browser/site_instance.h"
32 #include "content/public/browser/web_contents.h" 31 #include "content/public/browser/web_contents.h"
33 #include "extensions/browser/extension_host.h" 32 #include "extensions/browser/extension_host.h"
34 #include "extensions/browser/extension_system.h" 33 #include "extensions/browser/extension_system.h"
35 #include "extensions/browser/extensions_browser_client.h" 34 #include "extensions/browser/extensions_browser_client.h"
36 #include "extensions/browser/lazy_background_task_queue.h" 35 #include "extensions/browser/lazy_background_task_queue.h"
37 #include "extensions/browser/pref_names.h"
38 #include "extensions/browser/process_manager.h" 36 #include "extensions/browser/process_manager.h"
39 #include "extensions/common/extension.h" 37 #include "extensions/common/extension.h"
40 #include "extensions/common/manifest_constants.h" 38 #include "extensions/common/manifest_constants.h"
41 #include "extensions/common/manifest_handlers/background_info.h" 39 #include "extensions/common/manifest_handlers/background_info.h"
42 #include "extensions/common/manifest_handlers/externally_connectable.h" 40 #include "extensions/common/manifest_handlers/externally_connectable.h"
43 #include "extensions/common/manifest_handlers/incognito_info.h" 41 #include "extensions/common/manifest_handlers/incognito_info.h"
44 #include "extensions/common/permissions/permissions_data.h" 42 #include "extensions/common/permissions/permissions_data.h"
45 #include "net/base/completion_callback.h" 43 #include "net/base/completion_callback.h"
46 #include "url/gurl.h" 44 #include "url/gurl.h"
47 45
48 using content::BrowserContext; 46 using content::BrowserContext;
49 using content::SiteInstance; 47 using content::SiteInstance;
50 using content::WebContents; 48 using content::WebContents;
51 49
52 // Since we have 2 ports for every channel, we just index channels by half the 50 // Since we have 2 ports for every channel, we just index channels by half the
53 // port ID. 51 // port ID.
54 #define GET_CHANNEL_ID(port_id) ((port_id) / 2) 52 #define GET_CHANNEL_ID(port_id) ((port_id) / 2)
55 #define GET_CHANNEL_OPENER_ID(channel_id) ((channel_id) * 2) 53 #define GET_CHANNEL_OPENER_ID(channel_id) ((channel_id) * 2)
56 #define GET_CHANNEL_RECEIVERS_ID(channel_id) ((channel_id) * 2 + 1) 54 #define GET_CHANNEL_RECEIVERS_ID(channel_id) ((channel_id) * 2 + 1)
57 55
58 // Port1 is always even, port2 is always odd. 56 // Port1 is always even, port2 is always odd.
59 #define IS_OPENER_PORT_ID(port_id) (((port_id) & 1) == 0) 57 #define IS_OPENER_PORT_ID(port_id) (((port_id) & 1) == 0)
60 58
61 // Change even to odd and vice versa, to get the other side of a given channel. 59 // Change even to odd and vice versa, to get the other side of a given channel.
62 #define GET_OPPOSITE_PORT_ID(source_port_id) ((source_port_id) ^ 1) 60 #define GET_OPPOSITE_PORT_ID(source_port_id) ((source_port_id) ^ 1)
63 61
64 namespace extensions { 62 namespace extensions {
65 63
66 MessageService::PolicyPermission MessageService::IsNativeMessagingHostAllowed(
67 const PrefService* pref_service,
68 const std::string& native_host_name) {
69 PolicyPermission allow_result = ALLOW_ALL;
70 if (pref_service->IsManagedPreference(
71 pref_names::kNativeMessagingUserLevelHosts)) {
72 if (!pref_service->GetBoolean(pref_names::kNativeMessagingUserLevelHosts))
73 allow_result = ALLOW_SYSTEM_ONLY;
74 }
75
76 // All native messaging hosts are allowed if there is no blacklist.
77 if (!pref_service->IsManagedPreference(pref_names::kNativeMessagingBlacklist))
78 return allow_result;
79 const base::ListValue* blacklist =
80 pref_service->GetList(pref_names::kNativeMessagingBlacklist);
81 if (!blacklist)
82 return allow_result;
83
84 // Check if the name or the wildcard is in the blacklist.
85 base::StringValue name_value(native_host_name);
86 base::StringValue wildcard_value("*");
87 if (blacklist->Find(name_value) == blacklist->end() &&
88 blacklist->Find(wildcard_value) == blacklist->end()) {
89 return allow_result;
90 }
91
92 // The native messaging host is blacklisted. Check the whitelist.
93 if (pref_service->IsManagedPreference(
94 pref_names::kNativeMessagingWhitelist)) {
95 const base::ListValue* whitelist =
96 pref_service->GetList(pref_names::kNativeMessagingWhitelist);
97 if (whitelist && whitelist->Find(name_value) != whitelist->end())
98 return allow_result;
99 }
100
101 return DISALLOW;
102 }
103
104 const char kReceivingEndDoesntExistError[] = 64 const char kReceivingEndDoesntExistError[] =
105 "Could not establish connection. Receiving end does not exist."; 65 "Could not establish connection. Receiving end does not exist.";
106 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) 66 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
107 const char kMissingPermissionError[] = 67 const char kMissingPermissionError[] =
108 "Access to native messaging requires nativeMessaging permission."; 68 "Access to native messaging requires nativeMessaging permission.";
109 const char kProhibitedByPoliciesError[] = 69 const char kProhibitedByPoliciesError[] =
110 "Access to the native messaging host was disabled by the system " 70 "Access to the native messaging host was disabled by the system "
111 "administrator."; 71 "administrator.";
112 #endif 72 #endif
113 73
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 } 364 }
405 365
406 if (!has_permission) { 366 if (!has_permission) {
407 DispatchOnDisconnect(source, receiver_port_id, kMissingPermissionError); 367 DispatchOnDisconnect(source, receiver_port_id, kMissingPermissionError);
408 return; 368 return;
409 } 369 }
410 370
411 PrefService* pref_service = profile->GetPrefs(); 371 PrefService* pref_service = profile->GetPrefs();
412 372
413 // Verify that the host is not blocked by policies. 373 // Verify that the host is not blocked by policies.
414 PolicyPermission policy_permission = 374 NativeMessageProcessHost::PolicyPermission policy_permission =
415 IsNativeMessagingHostAllowed(pref_service, native_app_name); 375 NativeMessageProcessHost::IsHostAllowed(pref_service, native_app_name);
416 if (policy_permission == DISALLOW) { 376 if (policy_permission == NativeMessageProcessHost::DISALLOW) {
417 DispatchOnDisconnect(source, receiver_port_id, kProhibitedByPoliciesError); 377 DispatchOnDisconnect(source, receiver_port_id, kProhibitedByPoliciesError);
418 return; 378 return;
419 } 379 }
420 380
421 scoped_ptr<MessageChannel> channel(new MessageChannel()); 381 scoped_ptr<MessageChannel> channel(new MessageChannel());
422 channel->opener.reset(new ExtensionMessagePort(source, MSG_ROUTING_CONTROL, 382 channel->opener.reset(new ExtensionMessagePort(source, MSG_ROUTING_CONTROL,
423 source_extension_id)); 383 source_extension_id));
424 384
425 // Get handle of the native view and pass it to the native messaging host. 385 // Get handle of the native view and pass it to the native messaging host.
426 gfx::NativeView native_view = 386 gfx::NativeView native_view =
427 content::RenderWidgetHost::FromID(source_process_id, source_routing_id)-> 387 content::RenderWidgetHost::FromID(source_process_id, source_routing_id)->
428 GetView()->GetNativeView(); 388 GetView()->GetNativeView();
429 389
430 std::string error = kReceivingEndDoesntExistError; 390 scoped_ptr<NativeMessageProcessHost> native_process =
431 scoped_ptr<NativeMessageHost> native_host = NativeMessageHost::Create( 391 NativeMessageProcessHost::Create(
432 native_view, 392 native_view,
433 source_extension_id, 393 base::WeakPtr<NativeMessageProcessHost::Client>(
434 native_app_name, 394 weak_factory_.GetWeakPtr()),
435 policy_permission == ALLOW_ALL, 395 source_extension_id, native_app_name, receiver_port_id,
436 &error); 396 policy_permission == NativeMessageProcessHost::ALLOW_ALL);
437 397
438 // Abandon the channel. 398 // Abandon the channel.
439 if (!native_host.get()) { 399 if (!native_process.get()) {
440 LOG(ERROR) << "Failed to create native process."; 400 LOG(ERROR) << "Failed to create native process.";
441 DispatchOnDisconnect( 401 DispatchOnDisconnect(
442 source, receiver_port_id, error); 402 source, receiver_port_id, kReceivingEndDoesntExistError);
443 return; 403 return;
444 } 404 }
445 channel->receiver.reset(new NativeMessagePort( 405 channel->receiver.reset(new NativeMessagePort(native_process.release()));
446 weak_factory_.GetWeakPtr(), receiver_port_id, native_host.Pass()));
447 406
448 // Keep the opener alive until the channel is closed. 407 // Keep the opener alive until the channel is closed.
449 channel->opener->IncrementLazyKeepaliveCount(); 408 channel->opener->IncrementLazyKeepaliveCount();
450 409
451 AddChannel(channel.release(), receiver_port_id); 410 AddChannel(channel.release(), receiver_port_id);
452 #else // !(defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)) 411 #else // !(defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX))
453 const char kNativeMessagingNotSupportedError[] = 412 const char kNativeMessagingNotSupportedError[] =
454 "Native Messaging is not supported on this platform."; 413 "Native Messaging is not supported on this platform.";
455 DispatchOnDisconnect( 414 DispatchOnDisconnect(
456 source, receiver_port_id, kNativeMessagingNotSupportedError); 415 source, receiver_port_id, kNativeMessagingNotSupportedError);
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 if (iter == channels_.end()) { 555 if (iter == channels_.end()) {
597 // If this channel is pending, queue up the PostMessage to run once 556 // If this channel is pending, queue up the PostMessage to run once
598 // the channel opens. 557 // the channel opens.
599 EnqueuePendingMessage(source_port_id, channel_id, message); 558 EnqueuePendingMessage(source_port_id, channel_id, message);
600 return; 559 return;
601 } 560 }
602 561
603 DispatchMessage(source_port_id, iter->second, message); 562 DispatchMessage(source_port_id, iter->second, message);
604 } 563 }
605 564
565 void MessageService::PostMessageFromNativeProcess(int port_id,
566 const std::string& message) {
567 PostMessage(port_id, Message(message, false /* user_gesture */));
568 }
569
606 void MessageService::Observe(int type, 570 void MessageService::Observe(int type,
607 const content::NotificationSource& source, 571 const content::NotificationSource& source,
608 const content::NotificationDetails& details) { 572 const content::NotificationDetails& details) {
609 switch (type) { 573 switch (type) {
610 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: 574 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED:
611 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { 575 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
612 content::RenderProcessHost* renderer = 576 content::RenderProcessHost* renderer =
613 content::Source<content::RenderProcessHost>(source).ptr(); 577 content::Source<content::RenderProcessHost>(source).ptr();
614 OnProcessClosed(renderer); 578 OnProcessClosed(renderer);
615 break; 579 break;
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 } 755 }
792 756
793 void MessageService::DispatchOnDisconnect(content::RenderProcessHost* source, 757 void MessageService::DispatchOnDisconnect(content::RenderProcessHost* source,
794 int port_id, 758 int port_id,
795 const std::string& error_message) { 759 const std::string& error_message) {
796 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, ""); 760 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, "");
797 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(port_id), error_message); 761 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(port_id), error_message);
798 } 762 }
799 763
800 } // namespace extensions 764 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698