1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_CHANNEL_API_H_ 6 #define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_CHANNEL_API_H_ 7 8 #include <string> 9 10 #include "base/basictypes.h" 11 #include "base/memory/ref_counted.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/threading/thread_checker.h" 14 #include "extensions/browser/api/api_resource_manager.h" 15 #include "extensions/browser/api/async_api_function.h" 16 #include "extensions/browser/api/cast_channel/cast_socket.h" 17 #include "extensions/browser/browser_context_keyed_api_factory.h" 18 #include "extensions/common/api/cast_channel.h" 19 20 class GURL; 21 class CastChannelAPITest; 22 23 namespace content { 24 class BrowserContext; 25 } 26 27 namespace net { 28 class IPEndPoint; 29 } 30 31 namespace extensions { 32 33 namespace core_api { 34 namespace cast_channel { 35 class Logger; 36 } // namespace cast_channel 37 } // namespace core_api 38 39 namespace cast_channel = core_api::cast_channel; 40 41 class CastChannelAPI : public BrowserContextKeyedAPI, 42 public cast_channel::CastSocket::Delegate { 43 public: 44 explicit CastChannelAPI(content::BrowserContext* context); 45 46 static CastChannelAPI* Get(content::BrowserContext* context); 47 48 // BrowserContextKeyedAPI implementation. 49 static BrowserContextKeyedAPIFactory<CastChannelAPI>* GetFactoryInstance(); 50 51 // Returns a pointer to the Logger member variable. 52 // TODO(imcheng): Consider whether it is possible for this class to own the 53 // CastSockets and make this class the sole owner of Logger. 54 // Alternatively, 55 // consider making Logger not ref-counted by passing a weak 56 // reference of Logger to the CastSockets instead. 57 scoped_refptr<cast_channel::Logger> GetLogger(); 58 59 // Sets the CastSocket instance to be returned by CreateCastSocket for 60 // testing. 61 void SetSocketForTest(scoped_ptr<cast_channel::CastSocket> socket_for_test); 62 63 // Returns a test CastSocket instance, if it is defined. 64 // Otherwise returns a scoped_ptr with a NULL ptr value. 65 scoped_ptr<cast_channel::CastSocket> GetSocketForTest(); 66 67 private: 68 friend class BrowserContextKeyedAPIFactory<CastChannelAPI>; 69 friend class ::CastChannelAPITest; 70 71 virtual ~CastChannelAPI(); 72 73 // CastSocket::Delegate. Called on IO thread. 74 virtual void OnError(const cast_channel::CastSocket* socket, 75 cast_channel::ChannelError error_state, 76 const cast_channel::LastErrors& last_errors) OVERRIDE; 77 virtual void OnMessage(const cast_channel::CastSocket* socket, 78 const cast_channel::MessageInfo& message) OVERRIDE; 79 80 // BrowserContextKeyedAPI implementation. 81 static const char* service_name() { return "CastChannelAPI"; } 82 83 content::BrowserContext* const browser_context_; 84 scoped_refptr<cast_channel::Logger> logger_; 85 scoped_ptr<cast_channel::CastSocket> socket_for_test_; 86 87 DISALLOW_COPY_AND_ASSIGN(CastChannelAPI); 88 }; 89 90 class CastChannelAsyncApiFunction : public AsyncApiFunction { 91 public: 92 CastChannelAsyncApiFunction(); 93 94 protected: 95 virtual ~CastChannelAsyncApiFunction(); 96 97 // AsyncApiFunction: 98 virtual bool PrePrepare() OVERRIDE; 99 virtual bool Respond() OVERRIDE; 100 101 // Returns the socket corresponding to |channel_id| if one exists. Otherwise, 102 // sets the function result with CHANNEL_ERROR_INVALID_CHANNEL_ID, completes 103 // the function, and returns null. 104 cast_channel::CastSocket* GetSocketOrCompleteWithError(int channel_id); 105 106 // Adds |socket| to |manager_| and returns the new channel_id. |manager_| 107 // assumes ownership of |socket|. 108 int AddSocket(cast_channel::CastSocket* socket); 109 110 // Removes the CastSocket corresponding to |channel_id| from the resource 111 // manager. 112 void RemoveSocket(int channel_id); 113 114 // Sets the function result to a ChannelInfo obtained from the state of 115 // |socket|. 116 void SetResultFromSocket(const cast_channel::CastSocket& socket); 117 118 // Sets the function result to a ChannelInfo populated with |channel_id| and 119 // |error|. 120 void SetResultFromError(int channel_id, cast_channel::ChannelError error); 121 122 // Returns the socket corresponding to |channel_id| if one exists, or null 123 // otherwise. 124 cast_channel::CastSocket* GetSocket(int channel_id); 125 126 private: 127 // Sets the function result from |channel_info|. 128 void SetResultFromChannelInfo(const cast_channel::ChannelInfo& channel_info); 129 130 // The API resource manager for CastSockets. 131 ApiResourceManager<cast_channel::CastSocket>* manager_; 132 133 // The result of the function. 134 cast_channel::ChannelError error_; 135 }; 136 137 class CastChannelOpenFunction : public CastChannelAsyncApiFunction { 138 public: 139 CastChannelOpenFunction(); 140 141 protected: 142 virtual ~CastChannelOpenFunction(); 143 144 // AsyncApiFunction: 145 virtual bool PrePrepare() OVERRIDE; 146 virtual bool Prepare() OVERRIDE; 147 virtual void AsyncWorkStart() OVERRIDE; 148 149 private: 150 DECLARE_EXTENSION_FUNCTION("cast.channel.open", CAST_CHANNEL_OPEN) 151 152 // Parses the cast:// or casts:// |url|, fills |connect_info| with the 153 // corresponding details, and returns true. Returns false if |url| is not a 154 // valid Cast URL. 155 static bool ParseChannelUrl(const GURL& url, 156 cast_channel::ConnectInfo* connect_info); 157 158 // Validates that |connect_info| represents a valid IP end point and returns a 159 // new IPEndPoint if so. Otherwise returns NULL. 160 static net::IPEndPoint* ParseConnectInfo( 161 const cast_channel::ConnectInfo& connect_info); 162 163 void OnOpen(int result); 164 165 scoped_ptr<cast_channel::Open::Params> params_; 166 // The id of the newly opened socket. 167 int new_channel_id_; 168 CastChannelAPI* api_; 169 scoped_ptr<cast_channel::ConnectInfo> connect_info_; 170 scoped_ptr<net::IPEndPoint> ip_endpoint_; 171 cast_channel::ChannelAuthType channel_auth_; 172 173 FRIEND_TEST_ALL_PREFIXES(CastChannelOpenFunctionTest, TestParseChannelUrl); 174 FRIEND_TEST_ALL_PREFIXES(CastChannelOpenFunctionTest, TestParseConnectInfo); 175 DISALLOW_COPY_AND_ASSIGN(CastChannelOpenFunction); 176 }; 177 178 class CastChannelSendFunction : public CastChannelAsyncApiFunction { 179 public: 180 CastChannelSendFunction(); 181 182 protected: 183 virtual ~CastChannelSendFunction(); 184 185 // AsyncApiFunction: 186 virtual bool Prepare() OVERRIDE; 187 virtual void AsyncWorkStart() OVERRIDE; 188 189 private: 190 DECLARE_EXTENSION_FUNCTION("cast.channel.send", CAST_CHANNEL_SEND) 191 192 void OnSend(int result); 193 194 scoped_ptr<cast_channel::Send::Params> params_; 195 196 DISALLOW_COPY_AND_ASSIGN(CastChannelSendFunction); 197 }; 198 199 class CastChannelCloseFunction : public CastChannelAsyncApiFunction { 200 public: 201 CastChannelCloseFunction(); 202 203 protected: 204 virtual ~CastChannelCloseFunction(); 205 206 // AsyncApiFunction: 207 virtual bool Prepare() OVERRIDE; 208 virtual void AsyncWorkStart() OVERRIDE; 209 210 private: 211 DECLARE_EXTENSION_FUNCTION("cast.channel.close", CAST_CHANNEL_CLOSE) 212 213 void OnClose(int result); 214 215 scoped_ptr<cast_channel::Close::Params> params_; 216 217 DISALLOW_COPY_AND_ASSIGN(CastChannelCloseFunction); 218 }; 219 220 class CastChannelGetLogsFunction : public CastChannelAsyncApiFunction { 221 public: 222 CastChannelGetLogsFunction(); 223 224 protected: 225 virtual ~CastChannelGetLogsFunction(); 226 227 // AsyncApiFunction: 228 virtual bool PrePrepare() OVERRIDE; 229 virtual bool Prepare() OVERRIDE; 230 virtual void AsyncWorkStart() OVERRIDE; 231 232 private: 233 DECLARE_EXTENSION_FUNCTION("cast.channel.getLogs", CAST_CHANNEL_GETLOGS) 234 235 void OnClose(int result); 236 237 CastChannelAPI* api_; 238 239 DISALLOW_COPY_AND_ASSIGN(CastChannelGetLogsFunction); 240 }; 241 242 } // namespace extensions 243 244 #endif // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_CHANNEL_API_H_ 245