f11d8256b09c47b9644da60262a69785a2661352
[platform/core/uifw/dali-adaptor.git] / adaptors / base / performance-logging / networking / network-performance-client.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
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 express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "network-performance-client.h"
20
21 // EXTERNAL INCLUDES
22 #include <stdio.h>
23 #include <string>
24
25 // INTERNAL INCLUDES
26 #include <base/interfaces/socket-interface.h>
27 #include <base/performance-logging/networking/network-performance-protocol.h>
28 #include <base/performance-logging/networking/event/automation.h>
29
30
31 namespace Dali
32 {
33
34 namespace Internal
35 {
36
37 namespace Adaptor
38 {
39
40 namespace
41 {
42 const char UNKNOWN_CMD[]= "Command or parameter invalid, type help for list of commands\n";
43
44
45 /**
46  * helper class to store data along with the automation callback.
47  */
48 class AutomationCallback: public CallbackBase
49 {
50 public:
51
52   /**
53    * instead of using templates, or having different callback classes for each callback
54    * we use a command id that decides which static function to call on the Automation class.
55    */
56   enum CommandId
57   {
58     UNKNOWN_COMMAND,
59     SET_PROPERTY,
60     DUMP_SCENE
61   };
62
63   AutomationCallback(  unsigned int clientId, ClientSendDataInterface& sendDataInterface )
64   :CallbackBase( reinterpret_cast< void* >( this ),
65                  NULL, // we get the dispatcher to call function directly
66                  reinterpret_cast< CallbackBase::Dispatcher>( &AutomationCallback::Dispatcher) ),
67   mSendDataInterface( sendDataInterface ),
68   mCommandId( UNKNOWN_COMMAND ),
69   mClientId( clientId )
70   {}
71
72   void AssignSetPropertyCommand( std::string setPropertyCommand )
73   {
74     mCommandId = SET_PROPERTY;
75     mPropertyCommand = setPropertyCommand;
76   }
77   void AssignDumpSceneCommand()
78   {
79      mCommandId = DUMP_SCENE;
80   }
81
82   void RunCallback()
83   {
84     switch( mCommandId )
85     {
86       case SET_PROPERTY:
87       {
88         Automation::SetProperty( mPropertyCommand );
89         break;
90       }
91       case DUMP_SCENE:
92       {
93         Automation::DumpScene( mClientId, &mSendDataInterface);
94         break;
95       }
96       default:
97       {
98         DALI_ASSERT_DEBUG( 0 && "Unknown command");
99         break;
100       }
101     }
102   }
103   static void Dispatcher( CallbackBase& base )
104   {
105     AutomationCallback& automationCallback( static_cast< AutomationCallback& >( base) );
106     automationCallback.RunCallback();
107   }
108
109 private:
110
111   std::string mPropertyCommand;                   ///< property command
112   ClientSendDataInterface& mSendDataInterface;    ///< Abstract client send data interface
113   CommandId mCommandId;                           ///< command id
114   const unsigned int mClientId;                   ///< client id
115 };
116
117 } // unnamed namespace
118
119 NetworkPerformanceClient::NetworkPerformanceClient(  SocketInterface *socket,
120                                                      unsigned int clientId,
121                                                      TriggerEventFactoryInterface& triggerEventFactory,
122                                                      ClientSendDataInterface& sendDataInterface,
123                                                      SocketFactoryInterface& socketFactory )
124 : mSocket( socket ),
125   mMarkerBitmask( PerformanceMarker::FILTERING_DISABLED ),
126   mTriggerEventFactory( triggerEventFactory ),
127   mSendDataInterface( sendDataInterface ),
128   mSocketFactoryInterface( socketFactory ),
129   mClientId( clientId ),
130   mConsoleClient(false)
131 {
132
133 }
134
135 NetworkPerformanceClient::~NetworkPerformanceClient()
136 {
137   if( mSocket->SocketIsOpen() )
138   {
139     mSocket->CloseSocket();
140   }
141   mSocketFactoryInterface.DestroySocket( mSocket );
142 }
143
144 unsigned int NetworkPerformanceClient::GetId() const
145 {
146   return mClientId;
147 }
148
149 SocketInterface& NetworkPerformanceClient::GetSocket()
150 {
151   return *mSocket;
152 }
153
154 bool NetworkPerformanceClient::WriteSocket( const void* buffer, unsigned int bufferSizeInBytes )
155 {
156   return mSocket->Write( buffer, bufferSizeInBytes );
157 }
158
159 bool NetworkPerformanceClient::TransmitMarker( const PerformanceMarker& marker, const char* const description )
160 {
161   if( ! marker.IsFilterEnabled( mMarkerBitmask ) )
162   {
163     return true;
164   }
165   if( mConsoleClient )
166   {
167     // write out the time stamp
168     char buffer[64];
169     int size = snprintf( buffer, sizeof(buffer),"%d.%06d (seconds), %s\n",
170                                     marker.GetTimeStamp().seconds,
171                                     marker.GetTimeStamp().microseconds,
172                                     description );
173
174    return mSocket->Write( buffer, size );
175
176   }
177
178   // todo serialize the data
179   return false;
180 }
181
182 void NetworkPerformanceClient::ExitSelect()
183 {
184   mSocket->ExitSelect();
185 }
186
187
188 void NetworkPerformanceClient::ProcessCommand( char* buffer, unsigned int bufferSizeInBytes )
189 {
190   // if connected via console, then strip off the carriage return, and switch to console mode
191   if( buffer[ bufferSizeInBytes - 1] == '\n')
192   {
193     buffer[ bufferSizeInBytes - 1] = 0;
194     mConsoleClient = true;
195   }
196   unsigned int param(0);
197   std::string stringParam;
198   PerformanceProtocol::CommandId commandId( PerformanceProtocol::UNKNOWN_COMMAND );
199
200   bool ok =  PerformanceProtocol::GetCommandId( buffer, bufferSizeInBytes, commandId, param, stringParam );
201   if( !ok )
202   {
203     WriteSocket( UNKNOWN_CMD, sizeof(UNKNOWN_CMD) );
204     return;
205   }
206   std::string response;
207
208   switch( commandId )
209   {
210     case PerformanceProtocol::HELP_MESSAGE:
211     {
212       response = PerformanceProtocol::GetHelpMessage();
213       break;
214     }
215
216     case PerformanceProtocol::ENABLE_TIME_MARKER_BIT_MASK:
217     {
218       mMarkerBitmask  = static_cast<  PerformanceMarker::MarkerFilter >( param );
219       response = "enable time marker ";
220       break;
221     }
222
223     case PerformanceProtocol::DUMP_SCENE_GRAPH:
224     {
225       // this needs to be run on the main thread, use the trigger event....
226       AutomationCallback* callback = new AutomationCallback( mClientId, mSendDataInterface );
227       callback->AssignDumpSceneCommand();
228
229       // create a trigger event that automatically deletes itself after the callback has run in the main thread
230       TriggerEventInterface *interface = mTriggerEventFactory.CreateTriggerEvent( callback, TriggerEventInterface::DELETE_AFTER_TRIGGER );
231
232       // asynchronous call, the call back will be run sometime later on the main thread
233       interface->Trigger();
234       break;
235     }
236
237     case PerformanceProtocol::SET_PROPERTIES:
238     {
239       // this needs to be run on the main thread, use the trigger event....
240       AutomationCallback* callback = new AutomationCallback( mClientId, mSendDataInterface );
241       callback->AssignSetPropertyCommand( stringParam );
242
243       // create a trigger event that automatically deletes itself after the callback has run in the main thread
244       TriggerEventInterface *interface = mTriggerEventFactory.CreateTriggerEvent( callback, TriggerEventInterface::DELETE_AFTER_TRIGGER );
245
246       // asynchronous call, the call back will be run sometime later on the main thread
247       interface->Trigger();
248       break;
249     }
250
251     case PerformanceProtocol::LIST_METRICS_AVAILABLE:
252     case PerformanceProtocol::ENABLE_METRIC:
253     case PerformanceProtocol::DISABLE_METRIC:
254     {
255       response="Metrics currently not supported";
256       break;
257     }
258     default:
259     {
260       response = UNKNOWN_CMD;
261       break;
262     }
263   }
264   if( ! response.empty() )
265   {
266     // add a carriage return for console clients
267     if( mConsoleClient )
268     {
269       response+="\n";
270     }
271     WriteSocket( response.c_str(), response.length()  );
272   }
273 }
274
275
276
277 } // namespace Internal
278
279 } // namespace Adaptor
280
281 } // namespace Dali