1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 19 #ifndef PV_PROXIED_INTERFACE__H 20 #define PV_PROXIED_INTERFACE__H 21 22 23 #ifndef OSCL_BASE_H_INCLUDED 24 #include "oscl_base.h" 25 #endif 26 #ifndef PV_UUID_H_INCLUDED 27 #include "pv_uuid.h" 28 #endif 29 #ifndef PV_INTERFACE_H_INCLUDED 30 #include "pv_interface.h" 31 #endif 32 33 #define PVUidProxiedInterface PVUuid(0xf7076653,0x6088,0x47c6,0x88,0xc1,0xb7,0xed,0x28,0xe7,0x2b,0xea) 34 35 class PVProxiedInterface; 36 class PVProxiedInterfaceClient; 37 class PVProxiedInterfaceServer; 38 class PVProxiedEngine; 39 40 typedef int32 TPVProxyId; 41 typedef int32 TPVProxyMsgId; 42 typedef PVUuid TPVProxyUUID; 43 typedef PVProxiedInterface* TPVProxyInterfacePtr; 44 45 /** 46 ** Main proxy class. This class defines the public interface 47 ** to the PV proxy. 48 */ 49 class PVMainProxy 50 { 51 public: ~PVMainProxy()52 virtual ~PVMainProxy() {} 53 54 /** 55 ** This call registers a proxied interface with the main 56 ** proxy and assigns a unique interface ID. 57 ** Interfaces may be registered at any time during 58 ** the life of the main proxy. 59 ** 60 ** @return aProxyId: the ID of this interface pair. 61 ** @param aServer: server side (PV Thread) implementation. 62 ** @param aClient: client side (app thread) implementation. 63 ** This function will leave if memory allocation fails. 64 */ 65 virtual TPVProxyId RegisterProxiedInterface( 66 PVProxiedInterfaceServer& aServer, 67 PVProxiedInterfaceClient& aClient) = 0; 68 69 /** 70 ** This call un-registers a proxied interface with the main 71 ** proxy. During this call, the main proxy will de-queue all 72 ** undelivered messages belonging to this interface and will 73 ** call their memory cleanup routine. 74 ** If the interface is not currently registered, this call 75 ** will have no effect. 76 ** Interfaces may be un-registered at any time during the 77 ** life of the main proxy. 78 ** 79 ** @param aProxyId: the ID of this interface pair. 80 ** @return : result code 81 **/ 82 virtual void UnregisterProxiedInterface(TPVProxyId aProxyId) = 0; 83 84 /** 85 ** This API adds message to the command queue. This would 86 ** typically be called from a PVProxiedInterfaceClient 87 ** module. The message will be delivered asynchronously under 88 ** the PV thread. 89 ** 90 ** @param aProxyId: the ID of this interface pair. 91 ** @param aCmd: the command. 92 ** @return: a unique message ID, assigned by the proxy. 93 ** This function will leave if memory allocation fails. 94 **/ 95 virtual TPVProxyMsgId SendCommand(TPVProxyId aProxyId, OsclAny* aCmd) = 0; 96 97 /** 98 ** This API will cancel a command that was previously sent 99 ** and may still be queued. This is a synchronous operation. 100 ** The proxy will de-queue the message and call its memory cleanup 101 ** routine. If the message is no longer queued, this call will 102 ** have no effect. 103 ** 104 ** @param aProxyId: the ID of this interface pair. 105 ** @param aMsgId: the command's ID, previously returned by SendCommand. 106 ** @return : result code 107 */ 108 virtual void CancelCommand(TPVProxyId aProxyId, TPVProxyMsgId aMsgId) = 0; 109 110 /** 111 ** This API will de-queue and cleanup all commands that were 112 ** previously sent for an interface and may still be queued. 113 ** The cancel operation is synchronous. 114 ** If no commands are queued for the interface, this call has 115 ** no effect. 116 ** 117 ** @param aProxyId: the ID of this interface pair. 118 ** @return : result code 119 */ 120 virtual void CancelAllCommands(TPVProxyId aProxyId) = 0; 121 122 /** 123 ** This API adds a message to the notification queue. 124 ** This would typically be called by a PVProxiedInterfaceServer 125 ** module. The message will be delivered asynchronously under 126 ** the app thread. 127 ** 128 ** @param aProxyId: the ID of this interface pair. 129 ** @param aResp: the notification. 130 ** @return: a unique message ID, assigned by the proxy. 131 ** This function will leave if memory allocation fails. 132 **/ 133 virtual TPVProxyMsgId SendNotification(TPVProxyId aProxyId, OsclAny* aResp) = 0; 134 135 /** 136 ** This API will cancel a notification that was previously sent 137 ** and may still be queued. This is a synchronous operation. 138 ** The proxy will de-queue the message and call its memory cleanup 139 ** routine. If the message is no longer queued, this call will 140 ** have no effect. 141 ** 142 ** @param aProxyId: the ID of this interface pair. 143 ** @param aMsgId: the message ID, previously returned by SendNotification. 144 ** @return : result code 145 */ 146 virtual void CancelNotification(TPVProxyId aProxyId, TPVProxyMsgId aMsgId) = 0; 147 148 /** 149 ** This API will de-queue and cleanup all notifications that were 150 ** previously sent for an interface and may still be queued. 151 ** The cancel operation is synchronous. 152 ** If no notifications are queued for the interface, this call has 153 ** no effect. 154 ** 155 ** @param aProxyId: the ID of this interface pair. 156 ** @return : result code 157 */ 158 virtual void CancelAllNotifications(TPVProxyId aProxyId) = 0; 159 160 /** 161 ** This API will start the PV thread. The call will block 162 ** until the thread starts up and the engine thread logon 163 ** completes. 164 ** 165 ** @returns: true if thread creation succeeded-- false otherwise. 166 */ 167 virtual bool StartPVThread() = 0; 168 169 /** 170 ** This API will stop the PV thread's scheduler and block 171 ** until the thread cleanup is complete. During the thread 172 ** cleanup, the scheduler is stopped, all un-sent messages 173 ** are automatically cleaned up, and the engine Thread Logoff 174 ** routine is called. 175 ** 176 ** Calling this API under the PV thread context is an error 177 ** and will leave 178 */ 179 virtual void StopPVThread() = 0; 180 181 /** 182 ** This API may be used to run the client-side of the proxy 183 ** in a non-blocking mode, for cases where there is no Oscl 184 ** scheduler or native scheduler running in the application 185 ** thread. 186 ** The proxy client will run until all pending notifications 187 ** have been sent, or else the max count of notifications has 188 ** been reached. This API also returns the count of notifications 189 ** still pending after the processing is complete. 190 ** Any call to this API from within the PV thread context is 191 ** an error and will leave 192 ** 193 ** @param aMaxCount: (input param) the maximum of pending 194 ** notifications to process during the call. 195 ** @param aPendingCount: (output param) number of pending 196 ** notifications still remaining on the queue. 197 */ 198 virtual void DeliverNotifications(int32 aMaxCount, int32& aPendingCount) = 0; 199 }; 200 201 /** 202 ** A proxied engine must implement this class 203 */ 204 class PVProxiedEngine 205 { 206 public: ~PVProxiedEngine()207 virtual ~PVProxiedEngine() {} 208 209 /** 210 ** Create PV logger appenders for the PV thread. 211 ** Creating appenders in this call is optional and 212 ** allows logging by the PV thread related to thread 213 ** and scheduler initialization that occurs before 214 ** the thread logon. 215 **/ 216 virtual void CreateLoggerAppenders() = 0; 217 218 /** 219 ** Perform all thread-specific engine creation and 220 ** initialization. 221 ** This call is made by the main proxy from the PV 222 ** Thread after Oscl has been initialized 223 ** in the thread, but before starting the scheduler. 224 ** 225 ** @param proxy: reference to the caller. The app 226 ** may save this pointer and use it to make calls 227 ** to the main proxy. 228 */ 229 virtual void PVThreadLogon(PVMainProxy &proxy) = 0; 230 231 /** 232 ** Perform all thread-specific engine cleanup. 233 ** This call is made by the main proxy from the PV thread 234 ** after the scheduler has exited, but before Oscl has been 235 ** cleaned up. 236 ** 237 ** @param proxy: reference to the caller. The app 238 ** may save this pointer and use it to make calls 239 ** to the main proxy. 240 */ 241 virtual void PVThreadLogoff(PVMainProxy &proxy) = 0; 242 }; 243 244 /** 245 ** Proxied interface modules may implement this class 246 ** in order to provide a common interface query mechanism. 247 */ 248 class PVProxiedInterface : public PVInterface 249 { 250 public: 251 /** 252 ** To query for supported (proxied) interfaces. 253 ** 254 ** @param aUuid (input): the requested UUID 255 ** @param aInterfacePtr (output): a pointer to 256 ** the interface implementation, or NULL if not available. 257 ** 258 ** The holder of the interface pointer must call 259 ** "removeRef" when it is done with the pointer. 260 */ 261 virtual void QueryProxiedInterface(const TPVProxyUUID& aUuid, PVInterface*& aInterfacePtr) = 0; 262 /** 263 ** May be used to pass the main proxy pointer to 264 ** the implementation. 265 */ 266 virtual void SetMainProxy(PVMainProxy*) = 0; 267 }; 268 269 270 /** 271 ** Proxied interface modules must implement this class on the 272 ** PV thread side. 273 */ 274 class PVProxiedInterfaceServer 275 { 276 public: 277 /** 278 ** PVMainProxy calls this under the PV thread to process a 279 ** command off the queue. 280 ** 281 ** @param aId: the message ID assigned by the SendCommand call. 282 ** @param aMsg: the command data. 283 */ 284 virtual void HandleCommand(TPVProxyMsgId aMsgId, OsclAny* aMsg) = 0; 285 286 /** 287 ** PVMainProxy calls this to cleanup an un-sent or canceled 288 ** notification. The server module should clean up any 289 ** allocated memory. The cleanup operation must be synchronous 290 ** and thread-safe. 291 ** 292 ** @param aId: the message ID assigned by the SendNotification call. 293 ** @param aMsg: the notification data. 294 */ 295 virtual void CleanupNotification(TPVProxyMsgId aId, OsclAny* aMsg) = 0; 296 }; 297 298 /** 299 ** Proxied interface pairs must implement this class on the 300 ** app thread side. 301 */ 302 class PVProxiedInterfaceClient 303 { 304 public: PVProxiedInterfaceClient()305 PVProxiedInterfaceClient() {} 306 307 /** 308 ** PVMainProxy calls this to process a notification off the 309 ** queue. 310 ** @param aId: the message ID assigned by the SendNotification call. 311 ** @param aMsg: the notification data. 312 */ 313 virtual void HandleNotification(TPVProxyMsgId aId, OsclAny* aMsg) = 0; 314 315 /** 316 ** PVMainProxy calls this to cleanup an un-sent or canceled 317 ** command. The client module should clean up any allocated 318 ** memory. The cleanup operation must be synchronous 319 ** and thread-safe. 320 ** 321 ** @param aId: the message ID assigned by the SendCommand call. 322 ** @param aMsg: the command data. 323 */ 324 virtual void CleanupCommand(TPVProxyMsgId aId, OsclAny* aMsg) = 0; 325 }; 326 327 /** 328 //A basic implemention of PVProxiedInterface. 329 //Interface implementations 330 //can derive from this. 331 */ 332 template<class Alloc> 333 class PVProxiedInterfaceImpl : public PVProxiedInterface 334 { 335 public: PVProxiedInterfaceImpl(const PVUuid & uuid)336 PVProxiedInterfaceImpl(const PVUuid& uuid) 337 : iRefCounter(1) 338 , iUuid(uuid) 339 , iMainProxy(NULL) 340 {} SetUuid(const PVUuid & uuid)341 void SetUuid(const PVUuid& uuid) 342 { 343 iUuid = uuid; 344 } TestUuid(const PVUuid & uuid)345 bool TestUuid(const PVUuid& uuid) 346 { 347 return iUuid == uuid; 348 } ~PVProxiedInterfaceImpl()349 virtual ~PVProxiedInterfaceImpl() 350 {} removeRef()351 void removeRef() 352 { 353 --iRefCounter; 354 if (iRefCounter <= 0) 355 { 356 this->~PVProxiedInterfaceImpl(); 357 Alloc alloc; 358 alloc.deallocate(this); 359 } 360 } addRef()361 void addRef() 362 { 363 iRefCounter++; 364 } queryInterface(const PVUuid &,PVInterface * &)365 bool queryInterface(const PVUuid&, PVInterface*&) 366 { 367 return false; 368 } 369 SetMainProxy(PVMainProxy * p)370 void SetMainProxy(PVMainProxy*p) 371 { 372 iMainProxy = p; 373 } QueryProxiedInterface(const TPVProxyUUID & aUuid,PVInterface * & aInterfacePtr)374 void QueryProxiedInterface(const TPVProxyUUID& aUuid, PVInterface*& aInterfacePtr) 375 { 376 if (aUuid == iUuid) 377 aInterfacePtr = (PVInterface*)this; 378 else 379 aInterfacePtr = NULL; 380 } 381 protected: 382 int32 iRefCounter; 383 PVUuid iUuid; 384 PVMainProxy *iMainProxy; 385 }; 386 387 388 #endif 389 390 391