Release 8.0.0.15812
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia.Remoting / MediaController / MediaControlCommand.cs
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
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 using Tizen.Applications;
18 using System;
19 using System.Collections.Generic;
20 using NativeClient = Interop.MediaControllerClient;
21 using NativeServer = Interop.MediaControllerServer;
22 using NativeClientHandle = Interop.MediaControllerClientHandle;
23
24 namespace Tizen.Multimedia.Remoting
25 {
26     /// <summary>
27     /// Provides a means to send command to media control server.
28     /// </summary>
29     /// <since_tizen> 5 </since_tizen>
30     public abstract class Command
31     {
32         private string _requestId;
33
34         /// <summary>
35         /// The id for command receiver.
36         /// </summary>
37         /// <since_tizen> 5 </since_tizen>
38         protected string ReceiverId { get; private set; }
39
40         /// <summary>
41         /// Initializes a <see cref="Command"/> base class.
42         /// </summary>
43         /// <since_tizen> 5 </since_tizen>
44         protected Command() { }
45
46         /// <summary>
47         /// Sets the server information.
48         /// </summary>
49         /// <param name="receiverId">The receiver Id that receives command.</param>
50         internal void SetRequestInformation(string receiverId)
51         {
52             ReceiverId = receiverId ?? throw new ArgumentNullException(nameof(receiverId));
53         }
54
55         /// <summary>
56         /// Sets the client information.
57         /// </summary>
58         /// <param name="receiverId">The receiver Id that receives response for command.</param>
59         /// <param name="requestId">The request Id for each command.</param>
60         internal void SetResponseInformation(string receiverId, string requestId)
61         {
62             ReceiverId = receiverId ?? throw new ArgumentNullException(nameof(receiverId)); ;
63             _requestId = requestId ?? throw new ArgumentNullException(nameof(requestId)); ;
64         }
65
66         /// <summary>
67         /// Requests command to server.
68         /// </summary>
69         /// <returns>The request id for each command.</returns>
70         internal abstract string Request(NativeClientHandle clientHandle);
71
72         /// <summary>
73         /// Requests command to client.
74         /// </summary>
75         /// <param name="serverHandle"></param>
76         /// <returns>The request id for each command.</returns>
77         internal virtual string Request(IntPtr serverHandle) => throw new NotImplementedException();
78
79         /// <summary>
80         /// Represents a method that is called when an response command completes.
81         /// </summary>
82         /// <since_tizen> 5 </since_tizen>
83         protected virtual void OnResponseCompleted() { }
84
85         /// <summary>
86         /// Responses command to the client.
87         /// </summary>
88         /// <param name="serverHandle">The server handle.</param>
89         /// <param name="result">The result of each command.</param>
90         /// <param name="bundle">The extra data.</param>
91         internal void Response(IntPtr serverHandle, int result, Bundle bundle)
92         {
93             try
94             {
95                 if (bundle != null)
96                 {
97                     NativeServer.SendCommandReplyBundle(serverHandle, ReceiverId, _requestId, result, bundle.SafeBundleHandle)
98                         .ThrowIfError("Failed to response command.");
99                 }
100                 else
101                 {
102                     NativeServer.SendCommandReply(serverHandle, ReceiverId, _requestId, result, IntPtr.Zero)
103                         .ThrowIfError("Failed to response command.");
104                 }
105             }
106             catch (ArgumentException)
107             {
108                 throw new InvalidOperationException("Server is not running");
109             }
110             finally
111             {
112                 OnResponseCompleted();
113             }
114         }
115
116         /// <summary>
117         /// Responses command to the server.
118         /// </summary>
119         /// <param name="clientHandle">The client handle.</param>
120         /// <param name="result">The result of each command.</param>
121         /// <param name="bundle">The extra data.</param>
122         internal void Response(NativeClientHandle clientHandle, int result, Bundle bundle)
123         {
124             try
125             {
126                 if (bundle != null)
127                 {
128                     NativeClient.SendCustomEventReplyBundle(clientHandle, ReceiverId, _requestId, result, bundle.SafeBundleHandle)
129                         .ThrowIfError("Failed to response event.");
130                 }
131                 else
132                 {
133                     NativeClient.SendCustomEventReply(clientHandle, ReceiverId, _requestId, result, IntPtr.Zero)
134                         .ThrowIfError("Failed to response event.");
135                 }
136             }
137             catch (ArgumentException)
138             {
139                 throw new InvalidOperationException("Server is not running");
140             }
141             finally
142             {
143                 OnResponseCompleted();
144             }
145         }
146     }
147
148
149     /// <summary>
150     /// Provides a means to send playback command to media control server.
151     /// </summary>
152     public sealed class PlaybackCommand : Command
153     {
154         /// <summary>
155         /// Initializes a new instance of the <see cref="PlaybackCommand"/> class.
156         /// </summary>
157         /// <param name="action">A <see cref="MediaControlPlaybackCommand"/>.</param>
158         /// <exception cref="ArgumentException"><paramref name="action"/> is not valid.</exception>
159         /// <since_tizen> 5 </since_tizen>
160         public PlaybackCommand(MediaControlPlaybackCommand action)
161         {
162             ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), action, nameof(action));
163
164             Action = action;
165         }
166
167         /// <summary>
168         /// Gets the playback action.
169         /// </summary>
170         /// <since_tizen> 5 </since_tizen>
171         public MediaControlPlaybackCommand Action { get; }
172
173         internal override string Request(NativeClientHandle clientHandle)
174         {
175             ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), Action, nameof(Action));
176
177             NativeClient.SendPlaybackActionCommand(clientHandle, ReceiverId, Action.ToNative(), out string requestId)
178                 .ThrowIfError("Failed to send playback command.");
179
180             return requestId;
181         }
182     }
183
184     /// <summary>
185     /// Provides a means to send playback command to order specific time position.
186     /// </summary>
187     public sealed class PlaybackPositionCommand : Command
188     {
189         /// <summary>
190         /// Initializes a new instance of the <see cref="PlaybackPositionCommand"/> class.
191         /// </summary>
192         /// <param name="position">The playback position in milliseconds.</param>
193         /// <since_tizen> 5 </since_tizen>
194         public PlaybackPositionCommand(ulong position)
195         {
196             Position = position;
197         }
198
199         /// <summary>
200         /// Gets the position to play.
201         /// </summary>
202         /// <since_tizen> 5 </since_tizen>
203         public ulong Position { get; }
204
205         internal override string Request(NativeClientHandle clientHandle)
206         {
207             NativeClient.SendPlaybackPositionCommand(clientHandle, ReceiverId, Position, out string requestId)
208                 .ThrowIfError("Failed to send playback position command.");
209
210             return requestId;
211         }
212     }
213
214     /// <summary>
215     /// Provides a means to send playback command with playlist information.
216     /// </summary>
217     public sealed class PlaylistCommand : Command
218     {
219         /// <summary>
220         /// Initializes a new instance of the <see cref="PlaybackCommand"/> class.
221         /// </summary>
222         /// <param name="action">A <see cref="MediaControlPlaybackCommand"/>.</param>
223         /// <param name="playlistName">The playlist name of the server.</param>
224         /// <param name="index">The index of the media in the playlist.</param>
225         /// <param name="position">The playback position in milliseconds.</param>
226         /// <exception cref="ArgumentException"><paramref name="action"/>is not valid.</exception>
227         /// <exception cref="ArgumentNullException">
228         /// <paramref name="playlistName"/> or <paramref name="index"/> is null.
229         /// </exception>
230         /// <since_tizen> 5 </since_tizen>
231         public PlaylistCommand(MediaControlPlaybackCommand action, string playlistName, string index, ulong position)
232         {
233             ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), action, nameof(action));
234
235             Action = action;
236             Index = index ?? throw new ArgumentNullException(nameof(index));
237             Name = playlistName ?? throw new ArgumentNullException(nameof(playlistName));
238             Position = position;
239         }
240
241         /// <summary>
242         /// Initializes a new instance of the <see cref="PlaybackCommand"/> class.
243         /// </summary>
244         /// <param name="action">A <see cref="MediaControlPlaybackCommand"/>.</param>
245         /// <param name="playlistName">The playlist name of the server.</param>
246         /// <param name="index">The index of the media in the playlist.</param>
247         /// <exception cref="ArgumentNullException">
248         /// <paramref name="playlistName"/> or <paramref name="index"/> is null.
249         /// </exception>
250         /// <since_tizen> 5 </since_tizen>
251         public PlaylistCommand(MediaControlPlaybackCommand action, string playlistName, string index)
252             : this(action, playlistName, index, 0)
253         {
254         }
255
256         /// <summary>
257         /// Gets the playback action.
258         /// </summary>
259         /// <since_tizen> 5 </since_tizen>
260         public MediaControlPlaybackCommand Action { get; }
261
262         /// <summary>
263         /// Gets the position to play.
264         /// </summary>
265         /// <since_tizen> 5 </since_tizen>
266         public ulong Position { get; }
267
268         /// <summary>
269         /// Gets the index of playlist.
270         /// </summary>
271         /// <since_tizen> 5 </since_tizen>
272         public string Index { get; }
273
274         /// <summary>
275         /// Gets the name of playlist.
276         /// </summary>
277         /// <since_tizen> 5 </since_tizen>
278         public string Name { get; }
279
280         internal override string Request(NativeClientHandle clientHandle)
281         {
282             ValidationUtil.ValidateEnum(typeof(MediaControlPlaybackCommand), Action, nameof(Action));
283
284             NativeClient.SendPlaylistCommand(clientHandle, ReceiverId, Name, Index, Action.ToNative(),
285                 Position, out string requestId).ThrowIfError("Failed to send playlist command.");
286
287             return requestId;
288         }
289     }
290
291     /// <summary>
292     /// Provides a means to to send shuffle mode commands.
293     /// </summary>
294     /// <since_tizen> 5 </since_tizen>
295     public sealed class ShuffleModeCommand : Command
296     {
297         /// <summary>
298         /// Initializes a new instance of the <see cref="ShuffleModeCommand"/> class.
299         /// </summary>
300         /// <param name="enabled">A shuffle mode.</param>
301         /// <since_tizen> 5 </since_tizen>
302         public ShuffleModeCommand(bool enabled)
303         {
304             Enabled = enabled;
305         }
306
307         /// <summary>
308         /// Gets a value indicating whether the shuffle mode is enabled.
309         /// </summary>
310         public bool Enabled { get; }
311
312         internal override string Request(NativeClientHandle clientHandle)
313         {
314             var mode = Enabled ? MediaControllerNativeShuffleMode.On : MediaControllerNativeShuffleMode.Off;
315
316             NativeClient.SendShuffleModeCommand(clientHandle, ReceiverId, mode, out string requestId).
317                 ThrowIfError("Failed to send playback shuffle command.");
318
319             return requestId;
320         }
321     }
322
323     /// <summary>
324     /// Provides a means to to send repeat mode commands.
325     /// </summary>
326     /// <since_tizen> 5 </since_tizen>
327     public sealed class RepeatModeCommand : Command
328     {
329         /// <summary>
330         /// Initializes a new instance of the <see cref="RepeatModeCommand"/> class.
331         /// </summary>
332         /// <param name="mode">The <see cref="MediaControlRepeatMode"/>.</param>
333         /// <exception cref="ArgumentException"><paramref name="mode"/> is not valid.</exception>
334         /// <since_tizen> 5 </since_tizen>
335         public RepeatModeCommand(MediaControlRepeatMode mode)
336         {
337             ValidationUtil.ValidateEnum(typeof(MediaControlRepeatMode), mode, nameof(mode));
338
339             Mode = mode;
340         }
341
342         /// <summary>
343         /// Gets the repeat mode.
344         /// </summary>
345         /// <since_tizen> 5 </since_tizen>
346         public MediaControlRepeatMode Mode { get; }
347
348         internal override string Request(NativeClientHandle clientHandle)
349         {
350             ValidationUtil.ValidateEnum(typeof(MediaControlRepeatMode), Mode, nameof(Mode));
351
352             NativeClient.SendRepeatModeCommand(clientHandle, ReceiverId, Mode.ToNative(), out string requestId).
353                 ThrowIfError("Failed to send playback repeat command.");
354
355             return requestId;
356         }
357     }
358
359     /// <summary>
360     /// Provides a means to to send subtitle mode command.
361     /// </summary>
362     /// <since_tizen> 6 </since_tizen>
363     public sealed class SubtitleModeCommand : Command
364     {
365         /// <summary>
366         /// Initializes a new instance of the <see cref="SubtitleModeCommand"/> class.
367         /// </summary>
368         /// <param name="isEnabled">A value indicating whether subtitle mode is enabled.</param>
369         /// <since_tizen> 6 </since_tizen>
370         public SubtitleModeCommand(bool isEnabled)
371         {
372             IsEnabled = isEnabled;
373         }
374
375         /// <summary>
376         /// Gets a value indicating whether subtitle mode is enabled or not.
377         /// </summary>
378         /// <since_tizen> 6 </since_tizen>
379         public bool IsEnabled { get; }
380
381         internal override string Request(NativeClientHandle clientHandle)
382         {
383             NativeClient.SendSubtitleModeCommand(clientHandle, ReceiverId, IsEnabled, out string requestId).
384                 ThrowIfError("Failed to send subtitle mode command.");
385
386             return requestId;
387         }
388     }
389
390     /// <summary>
391     /// Provides a means to to send 360 mode command.
392     /// </summary>
393     /// <since_tizen> 6 </since_tizen>
394     public sealed class Mode360Command : Command
395     {
396         /// <summary>
397         /// Initializes a new instance of the <see cref="Mode360Command"/> class.
398         /// </summary>
399         /// <param name="isEnabled">A value indicating whether 360 mode is enabled or not.</param>
400         /// <since_tizen> 6 </since_tizen>
401         public Mode360Command(bool isEnabled)
402         {
403             IsEnabled = isEnabled;
404         }
405
406         /// <summary>
407         /// Gets a value indicating whether 360 mode is enabled or not.
408         /// </summary>
409         /// <since_tizen> 6 </since_tizen>
410         public bool IsEnabled { get; }
411
412         internal override string Request(NativeClientHandle clientHandle)
413         {
414             NativeClient.SendMode360Command(clientHandle, ReceiverId, IsEnabled, out string requestId).
415                 ThrowIfError("Failed to send 360 mode command.");
416
417             return requestId;
418         }
419     }
420
421     /// <summary>
422     /// Provides a means to to send display mode command.
423     /// </summary>
424     /// <since_tizen> 6 </since_tizen>
425     public sealed class DisplayModeCommand : Command
426     {
427         /// <summary>
428         /// Initializes a new instance of the <see cref="DisplayModeCommand"/> class.
429         /// </summary>
430         /// <param name="mode">The <see cref="MediaControlDisplayMode"/>.</param>
431         /// <exception cref="ArgumentException"><paramref name="mode"/> is not valid.</exception>
432         /// <since_tizen> 6 </since_tizen>
433         public DisplayModeCommand(MediaControlDisplayMode mode)
434         {
435             ValidationUtil.ValidateEnum(typeof(MediaControlDisplayMode), mode, nameof(mode));
436
437             Mode = mode;
438         }
439
440         /// <summary>
441         /// Gets the display mode.
442         /// </summary>
443         /// <since_tizen> 6 </since_tizen>
444         public MediaControlDisplayMode Mode { get; }
445
446         internal override string Request(NativeClientHandle clientHandle)
447         {
448             NativeClient.SendDisplayModeCommand(clientHandle, ReceiverId, Mode.ToNative(), out string requestId).
449                 ThrowIfError("Failed to send display mode command.");
450
451             return requestId;
452         }
453     }
454
455     /// <summary>
456     /// Provides a means to to send display rotation command.
457     /// </summary>
458     /// <since_tizen> 6 </since_tizen>
459     public sealed class DisplayRotationCommand : Command
460     {
461         /// <summary>
462         /// Initializes a new instance of the <see cref="DisplayRotationCommand"/> class.
463         /// </summary>
464         /// <param name="rotation">The <see cref="Rotation"/>.</param>
465         /// <exception cref="ArgumentException"><paramref name="rotation"/> is not valid.</exception>
466         /// <since_tizen> 6 </since_tizen>
467         public DisplayRotationCommand(Rotation rotation)
468         {
469             ValidationUtil.ValidateEnum(typeof(Rotation), rotation, nameof(rotation));
470
471             Rotation = rotation;
472         }
473
474         /// <summary>
475         /// Gets the display rotation.
476         /// </summary>
477         /// <since_tizen> 6 </since_tizen>
478         public Rotation Rotation { get; }
479
480         internal override string Request(NativeClientHandle clientHandle)
481         {
482             NativeClient.SendDisplayRotationCommand(clientHandle, ReceiverId, Rotation.ToNative(), out string requestId).
483                 ThrowIfError("Failed to send display rotation command.");
484
485             return requestId;
486         }
487     }
488
489     /// <summary>
490     /// Provides a means to to send custom commands.
491     /// </summary>
492     /// <remarks>This command can be used by both client and server to send predefined command or data.</remarks>
493     /// <since_tizen> 5 </since_tizen>
494     public sealed class CustomCommand : Command
495     {
496         /// <summary>
497         /// Initializes a new instance of the <see cref="CustomCommand"/> class.
498         /// </summary>
499         /// <param name="action">A predefined custom command.</param>
500         /// <since_tizen> 5 </since_tizen>
501         public CustomCommand(string action)
502         {
503             Action = action ?? throw new ArgumentNullException(nameof(action));
504         }
505
506         /// <summary>
507         /// Initializes a new instance of the <see cref="CustomCommand"/> class.
508         /// </summary>
509         /// <param name="action">A predefined custom command.</param>
510         /// <param name="bundle">The extra data for custom command.</param>
511         /// <since_tizen> 5 </since_tizen>
512         public CustomCommand(string action, Bundle bundle)
513             : this(action)
514         {
515             Bundle = bundle;
516         }
517
518         ///<summary>
519         /// Gets the custom action.
520         /// </summary>
521         /// <since_tizen> 5 </since_tizen>
522         public string Action { get; }
523
524         /// <summary>
525         /// Gets the extra data.
526         /// </summary>
527         /// <since_tizen> 5 </since_tizen>
528         public Bundle Bundle { get; }
529
530         internal override string Request(NativeClientHandle clientHandle)
531         {
532             string requestId = null;
533
534             if (Bundle != null)
535             {
536                 NativeClient.SendCustomCommandBundle(clientHandle, ReceiverId, Action, Bundle.SafeBundleHandle, out requestId).
537                     ThrowIfError("Failed to send custom command.");
538             }
539             else
540             {
541                 NativeClient.SendCustomCommand(clientHandle, ReceiverId, Action, IntPtr.Zero, out requestId).
542                     ThrowIfError("Failed to send custom command.");
543             }
544
545             return requestId;
546         }
547
548         internal override string Request(IntPtr serverHandle)
549         {
550             string requestId = null;
551
552             if (Bundle != null)
553             {
554                 NativeServer.SendCustomEventBundle(serverHandle, ReceiverId, Action, Bundle.SafeBundleHandle, out requestId)
555                     .ThrowIfError("Failed to send costom event.");
556             }
557             else
558             {
559                 NativeServer.SendCustomEvent(serverHandle, ReceiverId, Action, IntPtr.Zero, out requestId)
560                     .ThrowIfError("Failed to send costom event.");
561             }
562
563             return requestId;
564         }
565     }
566
567     /// <summary>
568     /// Provides a means to to send search commands.
569     /// </summary>
570     /// <since_tizen> 5 </since_tizen>
571     public sealed class SearchCommand : Command
572     {
573         private readonly IntPtr _searchHandle;
574
575         /// <summary>
576         /// Initializes a new instance of the <see cref="SearchCommand"/> class.
577         /// </summary>
578         /// <remarks>User can search maximum 20 items once.</remarks>
579         /// <exception cref="ArgumentNullException"><paramref name="conditions"/> is not set.</exception>
580         /// <exception cref="ArgumentException">
581         ///     <paramref name="conditions.Count"/> is greater than maximum value(20).<br/>
582         ///     -or-<br/>
583         ///     <paramref name="conditions.Count"/> is less than 1.
584         /// </exception>
585         /// <exception cref="InvalidOperationException">An internal error occurs.</exception>
586         /// <param name="conditions">The set of <see cref="MediaControlSearchCondition"/>.</param>
587         /// <since_tizen> 5 </since_tizen>
588         public SearchCommand(List<MediaControlSearchCondition> conditions)
589         {
590             if (conditions == null)
591             {
592                 throw new ArgumentNullException(nameof(conditions));
593             }
594             if (conditions.Count <= 0 || conditions.Count > 20)
595             {
596                 var errMessage = $"Invalid number of search conditions. : {conditions.Count}. " +
597                     $"Valid range is 1 ~ 20.";
598                 throw new ArgumentException(errMessage);
599             }
600
601             NativeClient.CreateSearchHandle(out _searchHandle).ThrowIfError("Failed to create search handle.");
602
603             try
604             {
605                 foreach (var condition in conditions)
606                 {
607                     if (condition.Bundle != null)
608                     {
609                         NativeClient.SetSearchConditionBundle(_searchHandle, condition.ContentType, condition.Category,
610                             condition.Keyword, condition.Bundle.SafeBundleHandle).
611                             ThrowIfError("Failed to set search condition.");
612                     }
613                     else
614                     {
615                         NativeClient.SetSearchCondition(_searchHandle, condition.ContentType, condition.Category,
616                             condition.Keyword, IntPtr.Zero).
617                             ThrowIfError("Failed to set search condition.");
618                     }
619                 }
620             }
621             catch
622             {
623                 if (_searchHandle != IntPtr.Zero)
624                 {
625                     NativeClient.DestroySearchHandle(_searchHandle).ThrowIfError("Failed to destroy search handle");
626                 }
627                 throw;
628             }
629         }
630
631         /// <summary>
632         /// Initializes a new instance of the <see cref="SearchCommand"/> class.
633         /// </summary>
634         /// <exception cref="ArgumentNullException"><paramref name="condition"/> is not set.</exception>
635         /// <exception cref="InvalidOperationException">An internal error occurs.</exception>
636         /// <param name="condition">The set of <see cref="MediaControlSearchCondition"/>.</param>
637         /// <since_tizen> 5 </since_tizen>
638         public SearchCommand(MediaControlSearchCondition condition)
639         {
640             if (condition == null)
641             {
642                 throw new ArgumentNullException(nameof(condition));
643             }
644
645             NativeClient.CreateSearchHandle(out _searchHandle).ThrowIfError("Failed to create search handle.");
646
647             try
648             {   
649                 if (condition.Bundle != null)
650                 {
651                     NativeClient.SetSearchConditionBundle(_searchHandle, condition.ContentType, condition.Category,
652                         condition.Keyword, condition.Bundle.SafeBundleHandle).
653                         ThrowIfError("Failed to set search condition.");
654                 }
655                 else
656                 {
657                     NativeClient.SetSearchCondition(_searchHandle, condition.ContentType, condition.Category,
658                         condition.Keyword, IntPtr.Zero).
659                         ThrowIfError("Failed to set search condition.");
660                 }
661             }
662             catch
663             {
664                 if (_searchHandle != IntPtr.Zero)
665                 {
666                     NativeClient.DestroySearchHandle(_searchHandle).ThrowIfError("Failed to destroy search handle");
667                 }
668                 throw;
669             }
670         }
671
672         /// <summary>
673         /// Initializes a new instance of the <see cref="SearchCommand"/> class by server side.
674         /// </summary>
675         internal SearchCommand(List<MediaControlSearchCondition> conditions, IntPtr searchHandle)
676         {
677             _searchHandle = searchHandle;
678             Conditions = conditions;
679         }
680
681         /// <summary>
682         /// Gets or sets the search conditions.
683         /// </summary>
684         /// <remarks>This property is used by MediaControlServer.</remarks>
685         /// <since_tizen> 5 </since_tizen>
686         public IEnumerable<MediaControlSearchCondition> Conditions { get; private set; }
687
688         internal override string Request(NativeClientHandle clientHandle)
689         {
690             NativeClient.SendSearchCommand(clientHandle, ReceiverId, _searchHandle, out string requestId).
691                 ThrowIfError("Failed to send search command.");
692
693             return requestId;
694         }
695
696         /// <summary>
697         /// Represents a method that is called when an response command completes.
698         /// </summary>
699         /// <since_tizen> 5 </since_tizen>
700         protected override void OnResponseCompleted()
701         {
702             base.OnResponseCompleted();
703         }
704     }
705 }