18bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file. 48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "remoting/host/native_messaging/pipe_messaging_channel.h" 68bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 78bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/basictypes.h" 88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/bind.h" 98bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/callback.h" 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/callback_helpers.h" 118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/location.h" 128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/values.h" 138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_POSIX) 158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include <unistd.h> 168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif 178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace { 198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)base::File DuplicatePlatformFile(base::File file) { 218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) base::PlatformFile result; 228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_WIN) 238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!DuplicateHandle(GetCurrentProcess(), 24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) file.TakePlatformFile(), 258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) GetCurrentProcess(), 268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) &result, 278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 0, 288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) FALSE, 298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) PLOG(ERROR) << "Failed to duplicate handle " << file.GetPlatformFile(); 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return base::File(); 328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return base::File(result); 348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#elif defined(OS_POSIX) 35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) result = dup(file.GetPlatformFile()); 36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return base::File(result); 378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#else 388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#error Not implemented. 398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif 408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} // namespace 438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)namespace remoting { 458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPipeMessagingChannel::PipeMessagingChannel( 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::File input, 48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::File output) 49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : native_messaging_reader_(DuplicatePlatformFile(input.Pass())), 508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) native_messaging_writer_(new NativeMessagingWriter( 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DuplicatePlatformFile(output.Pass()))), 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci event_handler_(NULL), 538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) weak_factory_(this) { 548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) weak_ptr_ = weak_factory_.GetWeakPtr(); 558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPipeMessagingChannel::~PipeMessagingChannel() { 588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PipeMessagingChannel::Start(EventHandler* event_handler) { 618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(CalledOnValidThread()); 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!event_handler_); 638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci event_handler_ = event_handler; 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(event_handler_); 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) native_messaging_reader_.Start( 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&PipeMessagingChannel::ProcessMessage, weak_ptr_), 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&PipeMessagingChannel::Shutdown, weak_ptr_)); 708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PipeMessagingChannel::ProcessMessage(scoped_ptr<base::Value> message) { 738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(CalledOnValidThread()); 748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (message->GetType() != base::Value::TYPE_DICTIONARY) { 768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) LOG(ERROR) << "Expected DictionaryValue"; 778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Shutdown(); 788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (event_handler_) 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci event_handler_->OnMessage(message.Pass()); 838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PipeMessagingChannel::SendMessage( 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<base::Value> message) { 878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(CalledOnValidThread()); 888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool success = message && native_messaging_writer_; 908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (success) 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) success = native_messaging_writer_->WriteMessage(*message); 928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!success) { 948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Close the write pipe so no more responses will be sent. 958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) native_messaging_writer_.reset(); 968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) Shutdown(); 978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PipeMessagingChannel::Shutdown() { 1018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) DCHECK(CalledOnValidThread()); 1028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (event_handler_) { 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Set event_handler_ to NULL to indicate the object is in a shutdown cycle. 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Since event_handler->OnDisconnect() will destroy the current object, 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |event_handler_| will become a dangling pointer after OnDisconnect() 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // returns. Therefore, we set |event_handler_| to NULL beforehand. 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EventHandler* handler = event_handler_; 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci event_handler_ = NULL; 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci handler->OnDisconnect(); 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} // namespace remoting 115