[NUI.Gadget] Support Internationalization (#5091)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Gadget / Tizen.NUI / NUIGadgetManager.cs
1 /*
2  * Copyright (c) 2023 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.Linq;
20 using System.IO;
21 using Tizen.Applications;
22 using System.ComponentModel;
23 using System.Runtime.InteropServices;
24 using System.Reflection;
25
26 namespace Tizen.NUI
27 {
28     /// <summary>
29     /// This class has the methods and events of the NUIGadgetManager.
30     /// </summary>
31     /// <since_tizen> 10 </since_tizen>
32     [EditorBrowsable(EditorBrowsableState.Never)]
33     public static class NUIGadgetManager
34     {
35         private static readonly Dictionary<string, NUIGadgetInfo> _gadgetInfos = new Dictionary<string, NUIGadgetInfo>();
36         private static readonly List<NUIGadget> _gadgets = new List<NUIGadget>();
37
38         static NUIGadgetManager()
39         {
40             IntPtr resPkgIds = Interop.Libc.GetEnviornmentVariable("RES_PKGIDS");
41             if (resPkgIds != IntPtr.Zero)
42             {
43                 string packages = Marshal.PtrToStringAnsi(resPkgIds);
44                 if (string.IsNullOrEmpty(packages))
45                 {
46                     Log.Warn("There is no resource packages");
47                 }
48                 else
49                 {
50                     foreach (string packageId in packages.Split(':').ToList())
51                     {
52                         NUIGadgetInfo info = NUIGadgetInfo.CreateNUIGadgetInfo(packageId);
53                         if (info != null)
54                         {
55                             _gadgetInfos.Add(info.ResourceType, info);
56                         }
57                     }
58                 }
59             }
60             else
61             {
62                 Log.Warn("Failed to get environment variable");
63             }
64
65             var context = (CoreApplication)CoreApplication.Current;
66             context.AppControlReceived += OnAppControlReceived;
67             context.LowMemory += OnLowMemory;
68             context.LowBattery += OnLowBattery;
69             context.LocaleChanged += OnLocaleChanged;
70             context.RegionFormatChanged += OnRegionFormatChanged;
71             context.DeviceOrientationChanged += OnDeviceOrientationChanged;
72         }
73
74         private static void OnAppControlReceived(object sender, AppControlReceivedEventArgs args)
75         {
76             HandleAppControl(args);
77         }
78
79         private static void OnLowMemory(object sender, LowMemoryEventArgs args)
80         {
81             HandleEvents(NUIGadgetEventType.LowMemory, args);
82         }
83
84         private static void OnLowBattery(object sender, LowBatteryEventArgs args)
85         {
86             HandleEvents(NUIGadgetEventType.LowBattery, args);
87         }
88
89         private static void OnLocaleChanged(object sender, LocaleChangedEventArgs args)
90         {
91             HandleEvents(NUIGadgetEventType.LocaleChanged, args);
92         }
93
94         private static void OnRegionFormatChanged(object sender, RegionFormatChangedEventArgs args)
95         {
96             HandleEvents(NUIGadgetEventType.RegionFormatChanged, args);
97         }
98
99         private static void OnDeviceOrientationChanged(object sender, DeviceOrientationEventArgs args)
100         {
101             HandleEvents(NUIGadgetEventType.DeviceORientationChanged, args);
102         }
103
104         /// <summary>
105         /// Occurs when the lifecycle of the NUIGadget is changed.
106         /// </summary>
107         /// <since_tizen> 10 </since_tizen>
108         public static event EventHandler<NUIGadgetLifecycleChangedEventArgs> NUIGadgetLifecycleChanged;
109
110         private static void OnNUIGadgetLifecycleChanged(object sender, NUIGadgetLifecycleChangedEventArgs args)
111         {
112             NUIGadgetLifecycleChanged?.Invoke(sender, args);
113
114             if (args.State == NUIGadgetLifecycleState.Destroyed)
115             {
116                 args.Gadget.LifecycleChanged -= OnNUIGadgetLifecycleChanged;
117                 _gadgets.Remove(args.Gadget);
118             }
119         }
120
121         /// <summary>
122         /// Adds a NUIGadget to a NUIGadgetManager.
123         /// </summary>
124         /// <param name="resourceType">The resource type of the NUIGadget package.</param>
125         /// <param name="className">The class name of the NUIGadget.</param>
126         /// <returns>The NUIGadget object.</returns>
127         /// <exception cref="ArgumentException">Thrown when failed because of a invalid argument.</exception>
128         /// <exception cref="InvalidOperationException">Thrown when failed because of an invalid operation.</exception>
129         /// <since_tizen> 10 </since_tizen>
130         public static NUIGadget Add(string resourceType, string className)
131         {
132             if (string.IsNullOrEmpty(resourceType) || string.IsNullOrEmpty(className))
133             {
134                 throw new ArgumentException("Invalid argument");
135             }
136
137             if (!_gadgetInfos.TryGetValue(resourceType, out NUIGadgetInfo info))
138             {
139                 throw new ArgumentException("Failed to find NUIGadgetInfo. resource type: " + resourceType);
140             }
141
142             Assembly assembly = null;
143             try
144             {
145                 Log.Warn("NUIGadgetAssembly.Load(): " + info.ResourcePath + info.ExecutableFile + " ++");
146                 assembly = Assembly.Load(File.ReadAllBytes(info.ResourcePath + info.ExecutableFile));
147                 Log.Warn("NUIGadgetAssembly.Load(): " + info.ResourcePath + info.ExecutableFile + " --");
148             }
149             catch (FileLoadException e)
150             {
151                 throw new InvalidOperationException(e.Message);
152             }
153
154             NUIGadget gadget = assembly.CreateInstance(className, true) as NUIGadget;
155             if (gadget == null)
156             {
157                 throw new InvalidOperationException("Failed to create instance. className: " + className);
158             }
159
160             gadget.NUIGadgetInfo = info;
161             gadget.ClassName = className;
162             gadget.NUIGadgetResourceManager = new NUIGadgetResourceManager(info);
163             gadget.LifecycleChanged += OnNUIGadgetLifecycleChanged;
164             if (!gadget.Create())
165             {
166                 throw new InvalidOperationException("The View MUST be created");
167             }
168
169             _gadgets.Add(gadget);
170             return gadget;
171         }
172
173         /// <summary>
174         /// Gets the instance of the running NUIGadgets.
175         /// </summary>
176         /// <returns>The NUIGadget list.</returns>
177         /// <since_tizen> 10 </since_tizen>
178         public static IEnumerable<NUIGadget> GetGadgets()
179         {
180             return _gadgets;
181         }
182
183         /// <summary>
184         /// Gets the information of the available NUIGadgets.
185         /// </summary>
186         /// <remarks>
187         /// This method only returns the available gadget informations, not all installed gadget informations.
188         /// The resource package of the NUIGadget can set the allowed packages using "allowed-package".
189         /// When executing an application, the platform mounts the resource package into the resource path of the application.
190         /// </remarks>
191         /// <returns>The NUIGadgetInfo list.</returns>
192         /// <since_tizen> 10 </since_tizen>
193         public static IEnumerable<NUIGadgetInfo> GetGadgetInfos()
194         {
195             return _gadgetInfos.Values.ToList();
196         }
197
198         /// <summary>
199         /// Removes the NUIGadget from a NUIGadgetManager.
200         /// </summary>
201         /// <param name="gadget">The NUIGadget object.</param>
202         /// <since_tizen> 10 </since_tizen>
203         public static void Remove(NUIGadget gadget)
204         {
205             if (gadget == null || !_gadgets.Contains(gadget))
206             {
207                 return;
208             }
209
210             if (gadget.State == NUIGadgetLifecycleState.Destroyed)
211             {
212                 return;
213             }
214
215             _gadgets.Remove(gadget);
216             CoreApplication.Post(() => {
217                 Log.Warn("ResourceType: " + gadget.NUIGadgetInfo.ResourceType + ", State: " + gadget.State);
218                 gadget.Finish();
219             });
220         }
221
222         /// <summary>
223         /// Removes all NUIGadget from a NUIGadgetManager.
224         /// </summary>
225         /// <since_tizen> 10 </since_tizen>
226         public static void RemoveAll()
227         {
228             for (int i = _gadgets.Count - 1;  i >= 0; i--)
229             {
230                 Remove(_gadgets[i]);
231             }
232         }
233
234         /// <summary>
235         /// Resumes the running NUIGadget.
236         /// </summary>
237         /// <param name="gadget">The NUIGadget object.</param>
238         /// <since_tizen> 10 </since_tizen>
239         public static void Resume(NUIGadget gadget)
240         {
241             if (!_gadgets.Contains(gadget))
242             {
243                 return;
244             }
245
246             CoreApplication.Post(() =>
247             {
248                 Log.Warn("ResourceType: " + gadget.NUIGadgetInfo.ResourceType + ", State: " + gadget.State);
249                 gadget.Resume();
250             });
251         }
252
253         /// <summary>
254         /// Pauses the running NUIGadget.
255         /// </summary>
256         /// <param name="gadget">The NUIGadget object.</param>
257         /// <since_tizen> 10 </since_tizen>
258         public static void Pause(NUIGadget gadget)
259         {
260             if (!_gadgets.Contains(gadget))
261             {
262                 return;
263             }
264
265             CoreApplication.Post(() =>
266             {
267                 Log.Warn("ResourceType: " + gadget.NUIGadgetInfo.ResourceType + ", State: " + gadget.State);
268                 gadget.Pause();
269             });
270         }
271
272         /// <summary>
273         /// Sends the appcontrol to the running NUIGadget.
274         /// </summary>
275         /// <param name="gadget">The NUIGadget object.</param>
276         /// <param name="appControl">The appcontrol object.</param>
277         /// <exception cref="ArgumentException">Thrown when failed because of a invalid argument.</exception>
278         /// <exception cref="ArgumentNullException">Thrown when failed because the argument is null.</exception>
279         /// <since_tizen> 10 </since_tizen>
280         public static void SendAppControl(NUIGadget gadget, AppControl appControl)
281         {
282             if (gadget == null)
283             {
284                 throw new ArgumentNullException(nameof(gadget));
285             }
286
287             if (!_gadgets.Contains(gadget))
288             {
289                 throw new ArgumentException("Invalid argument");
290             }
291
292             if (appControl == null)
293             {
294                 throw new ArgumentNullException(nameof(appControl));
295             }
296
297             gadget.HandleAppControlReceivedEvent(new AppControlReceivedEventArgs(new ReceivedAppControl(appControl.SafeAppControlHandle)));
298         }
299
300         internal static bool HandleAppControl(AppControlReceivedEventArgs args)
301         {
302             if (!args.ReceivedAppControl.ExtraData.TryGet("__K_GADGET_RES_TYPE", out string resourceType) ||
303                 !args.ReceivedAppControl.ExtraData.TryGet("__K_GADGET_CLASS_NAME", out string className))
304             {
305                 return false;
306             }
307
308             foreach (NUIGadget gadget in _gadgets)
309             {
310                 if (gadget.NUIGadgetInfo.ResourceType == resourceType && gadget.ClassName == className)
311                 {
312                     gadget.HandleAppControlReceivedEvent(args);
313                     return true;
314                 }
315             }
316
317             return false;
318         }
319
320         internal static void HandleEvents(NUIGadgetEventType eventType, EventArgs args)
321         {
322             foreach (NUIGadget gadget in _gadgets)
323             {
324                 gadget.HandleEvents(eventType, args);
325             }
326         }
327     }
328 }