[NUI] No need to do Registry.GetManagedBaseHandleFromNativePtr().
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / FrameBroker / FrameBrokerBase.cs
1 /*
2  * Copyright (c) 2020 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 System;
18 using System.Collections.Generic;
19 using System.ComponentModel;
20 using System.Threading.Tasks;
21 using Tizen.Applications;
22 using Tizen.Applications.Exceptions;
23
24 namespace Tizen.NUI
25 {
26     /// <summary>
27     /// Represents the Frame Broker.
28     /// </summary>
29     internal abstract class FrameBrokerBase : IDisposable
30     {
31         private string LogTag = "NUI";
32         private readonly SafeFrameBrokerHandle _handle;
33         private Dictionary<int, Interop.FrameBroker.AppControlResultCallback> _resultCallbackMaps = new Dictionary<int, Interop.FrameBroker.AppControlResultCallback>();
34         private int _resultId = 0;
35         private Interop.FrameBroker.FrameContextLifecycleCallbacks _callbacks;
36         private IntPtr _context = IntPtr.Zero;
37         private bool _disposed = false;
38
39         /// <summary>
40         /// Initializes the FrameBroker class.
41         /// </summary>
42         /// <param name="window">The window instance of Ecore_Wl2_Window pointer.</param>
43         /// <exception cref="ArgumentException">Thrown when failed because of an invalid parameter.</exception>
44         /// <exception cref="OutOfMemoryException">Thrown when the memory is insufficient.</exception>
45         /// <exception cref="InvalidOperationException">Thrown when failed to create the frame broker handle.</exception>
46         /// <remarks>This class is only avaliable for platform level signed applications.</remarks>
47         internal FrameBrokerBase(Window window)
48         {
49             Interop.FrameBroker.ErrorCode err;
50
51             if (window == null)
52             {
53                 throw FrameBrokerBaseErrorFactory.GetException(Interop.FrameBroker.ErrorCode.InvalidParameter, "Invalid parameter");
54             }
55
56             _callbacks.OnCreate = new Interop.FrameBroker.FrameContextCreateCallback(OnCreateNative);
57             _callbacks.OnResume = new Interop.FrameBroker.FrameContextResumeCallback(OnResumeNavie);
58             _callbacks.OnPause = new Interop.FrameBroker.FrameContextPauseCallback(OnPauseNative);
59             _callbacks.OnDestroy = new Interop.FrameBroker.FrameContextDestroyCallback(OnDestroyNative);
60             _callbacks.OnError = new Interop.FrameBroker.FrameContextErrorCallback(OnErrorNative);
61             _callbacks.OnUpdate = new Interop.FrameBroker.FrameContextUpdateCallback(OnUpdateNative);
62
63             err = Interop.FrameBroker.Create(window.GetNativeWindowHandler(), ref _callbacks, IntPtr.Zero, out _handle);
64             if (err != Interop.FrameBroker.ErrorCode.None)
65             {
66                 throw FrameBrokerBaseErrorFactory.GetException(err, "Failed to create frame broker handle");
67             }
68         }
69
70         /// <summary>
71         /// Sends the launch request asynchronously.
72         /// </summary>
73         /// <remarks>
74         /// The operation is mandatory information for the launch request.
75         /// If the operation is not specified, AppControlOperations.Default is used by default.
76         /// If the operation is AppControlOperations.Default, the application ID is mandatory to explicitly launch the application.<br/>
77         /// Since Tizen 2.4, the launch request of the service application over out of packages is restricted by the platform.
78         /// Also, implicit launch requests are NOT delivered to service applications since 2.4.
79         /// To launch a service application, an explicit launch request with the application ID given by property ApplicationId MUST be sent.
80         /// </remarks>
81         /// <param name="appControl">The AppControl.</param>
82         /// <param name="toProvider"> The flag, if it's true, the launch request is sent to the frame provider application.</param>
83         /// <returns>A task with the result of the launch request.</returns>
84         /// <exception cref="ArgumentException">Thrown when failed because of the argument is invalid.</exception>
85         /// <exception cref="AppNotFoundException">Thrown when the application to run is not found.</exception>
86         /// <exception cref="LaunchRejectedException">Thrown when the launch request is rejected.</exception>
87         /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
88         internal Task<FrameBrokerBaseResult> SendLaunchRequest(AppControl appControl, bool toProvider)
89         {
90             if (appControl == null)
91             {
92                 throw FrameBrokerBaseErrorFactory.GetException(Interop.FrameBroker.ErrorCode.InvalidParameter, "Invalid parameter");
93             }
94
95             var task = new TaskCompletionSource<FrameBrokerBaseResult>();
96             int requestId = 0;
97
98             lock (_resultCallbackMaps)
99             {
100                 requestId = _resultId++;
101                 _resultCallbackMaps[requestId] = (handle, result, userData) =>
102                 {
103                     task.SetResult((FrameBrokerBaseResult)result);
104                     lock (_resultCallbackMaps)
105                     {
106                         _resultCallbackMaps.Remove((int)userData);
107                     }
108                 };
109             }
110
111             Interop.FrameBroker.ErrorCode err;
112             if (toProvider)
113                 err = Interop.FrameBroker.SendLaunchRequestToProvider(_handle, appControl.SafeAppControlHandle, _resultCallbackMaps[requestId], null, (IntPtr)requestId);
114             else
115                 err = Interop.FrameBroker.SendLaunchRequest(_handle, appControl.SafeAppControlHandle, _resultCallbackMaps[requestId], null, (IntPtr)requestId);
116
117             if (err != Interop.FrameBroker.ErrorCode.None)
118             {
119                 throw FrameBrokerBaseErrorFactory.GetException(err, "Failed to send launch request");
120             }
121
122             return task.Task;
123         }
124
125         /// <summary>
126         /// Notifies that the animation is started.
127         /// </summary>
128         /// <exception cref="ArgumentException">Thrown when failed because of the argument is invalid.</exception>
129         /// <exception cref="InvalidOperationException">Thrown when failed because of system error.</exception>
130         internal void StartAnimation()
131         {
132             Interop.FrameBroker.ErrorCode err = Interop.FrameBroker.StartAnimation(_context);
133             if (err != Interop.FrameBroker.ErrorCode.None)
134             {
135                 throw FrameBrokerBaseErrorFactory.GetException(err, "Failed to notify that the animation is started");
136             }
137         }
138
139         /// <summary>
140         /// Notifies that the animation is finished.
141         /// </summary>
142         /// <exception cref="ArgumentException">Thrown when failed because of the argument is invalid.</exception>
143         /// <exception cref="InvalidOperationException">Thrown when failed because of system error.</exception>
144         internal void FinishAnimation()
145         {
146             Interop.FrameBroker.ErrorCode err = Interop.FrameBroker.FinishAnimation(_context);
147             if (err != Interop.FrameBroker.ErrorCode.None)
148             {
149                 throw FrameBrokerBaseErrorFactory.GetException(err, "Failed to notify that the animation is finished");
150             }
151         }
152
153         /// <summary>
154         /// Occurs whenever the frame is created.
155         /// </summary>
156         [EditorBrowsable(EditorBrowsableState.Never)]
157         protected virtual void OnFrameCreated()
158         {
159             Log.Warn(LogTag, "The OnFrameCreated() is not implemented");
160         }
161
162         /// <summary>
163         /// Occurs Whenever the frame is resumed.
164         /// </summary>
165         /// <param name="frame">The frame data.</param>
166         /// <remarks>
167         /// When the frame has been prepared, this function is called.
168         /// The caller can start animations, To notify that the animation is started, the caller should call StartAnimation().
169         /// After the animation is finished, the caller should call FinishAnimation() to notify.
170         /// </remarks>
171         [EditorBrowsable(EditorBrowsableState.Never)]
172         protected virtual void OnFrameResumed(FrameData frame)
173         {
174             Log.Warn(LogTag, "The OnFrameResumed() is not implemented");
175         }
176
177         /// <summary>
178         /// Occurs Whenever the frame is updated.
179         /// </summary>
180         /// <param name="frame">The frame data.</param>
181         [EditorBrowsable(EditorBrowsableState.Never)]
182         protected virtual void OnFrameUpdated(FrameData frame)
183         {
184             Log.Warn(LogTag, "The OnFrameUpdated() is not implemented");
185         }
186
187         /// <summary>
188         /// Occurs Whenever the frame is paused.
189         /// </summary>
190         [EditorBrowsable(EditorBrowsableState.Never)]
191         protected virtual void OnFramePaused()
192         {
193             Log.Warn(LogTag, "The OnFramePaused() is not implemented");
194         }
195
196         /// <summary>
197         /// Occurs Whenever the frame is destroyed.
198         /// </summary>
199         [EditorBrowsable(EditorBrowsableState.Never)]
200         protected virtual void OnFrameDestroyed()
201         {
202             Log.Warn(LogTag, "The OnFrameDestroyed() is not implemented");
203         }
204
205         /// <summary>
206         /// Occurs Whenever the system error is occurred.
207         /// </summary>
208         /// <param name="error">The frame error.</param>
209         [EditorBrowsable(EditorBrowsableState.Never)]
210         protected virtual void OnFrameErred(FrameError error)
211         {
212             Log.Warn(LogTag, "The OnFrameErred() is not implemented");
213         }
214                 
215         private void OnCreateNative(IntPtr context, IntPtr userData)
216         {
217             _context = context;
218             OnFrameCreated();
219         }
220
221         private void OnResumeNavie(IntPtr context, IntPtr frame, IntPtr userData)
222         {
223             OnFrameResumed(new FrameData(frame));
224         }
225
226         private void OnPauseNative(IntPtr context, IntPtr userData)
227         {
228             OnFramePaused();
229         }
230
231         private void OnDestroyNative(IntPtr context, IntPtr userData)
232         {
233             _context = IntPtr.Zero;
234             OnFrameDestroyed();
235         }
236
237         private void OnErrorNative(IntPtr context, int error, IntPtr userData)
238         {
239             _context = IntPtr.Zero;
240             OnFrameErred((FrameError)error);
241         }
242
243         private void OnUpdateNative(IntPtr context, IntPtr frame, IntPtr userData)
244         {
245             OnFrameUpdated(new FrameData(frame));
246         }
247
248         [EditorBrowsable(EditorBrowsableState.Never)]
249         protected virtual void Dispose(bool disposing)
250         {
251             if (!_disposed)
252             {
253                 _handle.Dispose();
254                 _disposed = true;
255             }
256         }
257
258         [EditorBrowsable(EditorBrowsableState.Never)]
259         public void Dispose()
260         {
261             Dispose(true);
262
263         }
264     }
265 }