9706a3435d3c27ae0f131b5c5f37f176c8a5ed90
[platform/core/csapi/xsf.git] / src / XSF / Xamarin.Forms.Platform.Tizen / Forms.cs
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Linq;
5 using System.Linq.Expressions;
6 using System.Reflection;
7 using Xamarin.Forms.Internals;
8 using Xamarin.Forms.Platform.Tizen;
9 using ElmSharp;
10 using Tizen.Applications;
11 using TSystemInfo = Tizen.System.Information;
12 using TSystemSetting = Tizen.System.SystemSettings;
13 using EWindow = ElmSharp.Window;
14 using ELayout = ElmSharp.Layout;
15 using DeviceOrientation = Xamarin.Forms.Internals.DeviceOrientation;
16 using Xamarin.Forms.PlatformConfiguration.TizenSpecific;
17 using ElmSharp.Wearable;
18 using Tizen.Wearable.CircularUI.Forms;
19
20 namespace Xamarin.Forms
21 {
22         public enum StaticRegistrarStrategy
23         {
24                 None,
25                 StaticRegistrarOnly,
26                 All,
27         }
28
29         public enum PlatformType
30         {
31                 Defalut,
32                 Lightweight,
33         }
34
35         public class InitializationOptions
36         {
37                 public CoreApplication Context { get; set; }
38                 public bool UseDeviceIndependentPixel { get; set; }
39                 public HandlerAttribute[] Handlers { get; set; }
40                 public Dictionary<Type, Func<IRegisterable>> CustomHandlers { get; set; } // for static registers
41                 public Assembly[] Assemblies { get; set; }
42                 public EffectScope[] EffectScopes { get; set; }
43                 public InitializationFlags Flags { get; set; }
44                 public StaticRegistrarStrategy StaticRegistarStrategy { get; set; }
45                 public PlatformType PlatformType { get; set; }
46                 public bool UseMessagingCenter { get; set; } = true;
47                 public bool UseStyle { get; set; } = true;
48                 public bool UseShell { get; set; } = true;
49                 public bool UseVisual { get; set; } = true;
50
51
52                 public struct EffectScope
53                 {
54                         public string Name;
55                         public ExportEffectAttribute[] Effects;
56                 }
57
58                 public InitializationOptions(CoreApplication application)
59                 {
60                         Context = application;
61                 }
62
63                 public InitializationOptions(CoreApplication application, bool useDeviceIndependentPixel, HandlerAttribute[] handlers)
64                 {
65                         Context = application;
66                         UseDeviceIndependentPixel = useDeviceIndependentPixel;
67                         Handlers = handlers;
68                 }
69
70                 public InitializationOptions(CoreApplication application, bool useDeviceIndependentPixel, params Assembly[] assemblies)
71                 {
72                         Context = application;
73                         UseDeviceIndependentPixel = useDeviceIndependentPixel;
74                         Assemblies = assemblies;
75                 }
76
77                 public void UseStaticRegistrar(StaticRegistrarStrategy strategy, Dictionary<Type, Func<IRegisterable>> customHandlers = null, bool disableCss = false)
78                 {
79                         StaticRegistarStrategy = strategy;
80                         CustomHandlers = customHandlers;
81                         if (disableCss) // about 10ms
82                                 Flags = InitializationFlags.DisableCss;
83                 }
84         }
85
86         public static class Forms
87         {
88                 static Lazy<string> s_profile = new Lazy<string>(() =>
89                 {
90                         //TODO : Fix me if elm_config_profile_get() unavailable
91                         return Elementary.GetProfile();
92                 });
93
94                 static Lazy<int> s_dpi = new Lazy<int>(() =>
95                 {
96                         int dpi = 0;
97                         if (s_profile.Value == "tv")
98                         {
99                                 // Use fixed DPI value (72) if TV profile
100                                 return 72;
101                         }
102                         TSystemInfo.TryGetValue<int>("http://tizen.org/feature/screen.dpi", out dpi);
103                         return dpi;
104                 });
105
106                 static Lazy<double> s_elmScale = new Lazy<double>(() =>
107                 {
108                         // 72.0 is from EFL which is using fixed DPI value (72.0) to determine font size internally. Thus, we are restoring the size by deviding the DPI by 72.0 here.
109                         return s_dpi.Value / 72.0 / Elementary.GetScale();
110                 });
111
112                 class TizenDeviceInfo : DeviceInfo
113                 {
114                         readonly Size pixelScreenSize;
115
116                         readonly Size scaledScreenSize;
117
118                         readonly double scalingFactor;
119
120                         readonly string profile;
121
122                         public override Size PixelScreenSize
123                         {
124                                 get
125                                 {
126                                         return this.pixelScreenSize;
127                                 }
128                         }
129
130                         public override Size ScaledScreenSize
131                         {
132                                 get
133                                 {
134                                         return this.scaledScreenSize;
135                                 }
136                         }
137
138                         public override double ScalingFactor
139                         {
140                                 get
141                                 {
142                                         return this.scalingFactor;
143                                 }
144                         }
145
146                         public string Profile
147                         {
148                                 get
149                                 {
150                                         return this.profile;
151                                 }
152                         }
153
154                         public TizenDeviceInfo() : this(getScreenWidth(), getScreenHeight())
155                         {
156                         }
157
158                         static int getScreenWidth()
159                         {
160                                 if (TSystemInfo.TryGetValue("http://tizen.org/feature/screen.width", out int width))
161                                 {
162                                         return width;
163                                 }
164                                 else
165                                 {
166                                         throw new InvalidOperationException("Can not get screen.Width");
167                                 }
168                         }
169                         static int getScreenHeight()
170                         {
171                                 if (TSystemInfo.TryGetValue("http://tizen.org/feature/screen.height", out int height))
172                                 {
173                                         return height;
174                                 }
175                                 else
176                                 {
177                                         throw new InvalidOperationException("Can not get screen.Height");
178                                 }
179                         }
180                         TizenDeviceInfo(int width, int height)
181                         {
182                                 pixelScreenSize = new Size(width, height);
183
184                                 scalingFactor = 1.0;  // scaling is disabled, we're using pixels as Xamarin's geometry units
185                                 if (s_useDeviceIndependentPixel)
186                                 {
187                                         scalingFactor = s_dpi.Value / 160.0;
188                                 }
189
190                                 scaledScreenSize = new Size(width / scalingFactor, height / scalingFactor);
191                                 profile = s_profile.Value;
192                         }
193
194                         public TizenDeviceInfo RefreshByDIP()
195                         {
196                                 return new TizenDeviceInfo((int)pixelScreenSize.Width, (int)pixelScreenSize.Height);
197                         }
198                 }
199
200                 static bool s_useDeviceIndependentPixel = false;
201
202                 static StaticRegistrarStrategy s_staticRegistrarStrategy = StaticRegistrarStrategy.None;
203
204                 static PlatformType s_platformType = PlatformType.Defalut;
205
206                 static bool s_useMessagingCenter = true;
207
208                 public static event EventHandler<ViewInitializedEventArgs> ViewInitialized;
209
210                 public static CoreApplication Context
211                 {
212                         get;
213                         internal set;
214                 }
215
216                 public static EvasObject NativeParent
217                 {
218                         get; internal set;
219                 }
220
221                 public static ELayout BaseLayout => NativeParent as ELayout;
222
223                 public static CircleSurface CircleSurface
224                 {
225                         get; internal set;
226                 }
227
228                 [EditorBrowsable(EditorBrowsableState.Never)]
229                 public static Element RotaryFocusObject
230                 {
231                         get; internal set;
232                 }
233
234                 public static bool IsInitialized
235                 {
236                         get;
237                         private set;
238                 }
239
240                 public static bool IsPreloaded
241                 {
242                         get;
243                         private set;
244                 }
245
246                 public static DeviceOrientation NaturalOrientation { get; } = GetDeviceOrientation();
247
248                 public static StaticRegistrarStrategy StaticRegistrarStrategy => s_staticRegistrarStrategy;
249
250                 public static PlatformType PlatformType => s_platformType;
251
252                 public static bool UseMessagingCenter => s_useMessagingCenter;
253
254                 internal static TizenTitleBarVisibility TitleBarVisibility
255                 {
256                         get;
257                         private set;
258                 }
259
260                 static DeviceOrientation GetDeviceOrientation()
261                 {
262                         int width = 0;
263                         int height = 0;
264                         TSystemInfo.TryGetValue<int>("http://tizen.org/feature/screen.width", out width);
265                         TSystemInfo.TryGetValue<int>("http://tizen.org/feature/screen.height", out height);
266
267                         if (height >= width)
268                         {
269                                 return DeviceOrientation.Portrait;
270                         }
271                         else
272                         {
273                                 return DeviceOrientation.Landscape;
274                         }
275                 }
276
277                 internal static void SendViewInitialized(this VisualElement self, EvasObject nativeView)
278                 {
279                         EventHandler<ViewInitializedEventArgs> viewInitialized = Forms.ViewInitialized;
280                         if (viewInitialized != null)
281                         {
282                                 viewInitialized.Invoke(self, new ViewInitializedEventArgs
283                                 {
284                                         View = self,
285                                         NativeView = nativeView
286                                 });
287                         }
288                 }
289
290                 static IReadOnlyList<string> s_flags;
291                 public static IReadOnlyList<string> Flags => s_flags ?? (s_flags = new string[0]);
292
293                 public static void SetFlags(params string[] flags)
294                 {
295                         if (IsInitialized)
296                         {
297                                 throw new InvalidOperationException($"{nameof(SetFlags)} must be called before {nameof(Init)}");
298                         }
299
300                         s_flags = (string[])flags.Clone();
301                         if (s_flags.Contains("Profile"))
302                                 Profile.Enable();
303                 }
304
305                 public static void SetTitleBarVisibility(TizenTitleBarVisibility visibility)
306                 {
307                         TitleBarVisibility = visibility;
308                 }
309
310                 public static TOut GetHandler<TOut>(Type type, params object[] args) where TOut : class, IRegisterable
311                 {
312                         if (s_staticRegistrarStrategy == StaticRegistrarStrategy.None)
313                         {
314                                 // Find hander in internal registrar, that is using reflection (default).
315                                 return Internals.Registrar.Registered.GetHandler<TOut>(type, args);
316                         }
317                         else
318                         {
319                                 // 1. Find hander in static registrar first
320                                 TOut ret = StaticRegistrar.Registered.GetHandler<TOut>(type, args);
321
322                                 // 2. If there is no handler, try to find hander in internal registrar, that is using reflection.
323                                 if (ret == null && s_staticRegistrarStrategy == StaticRegistrarStrategy.All)
324                                 {
325                                         ret = Internals.Registrar.Registered.GetHandler<TOut>(type, args);
326                                 }
327                                 return ret;
328                         }
329                 }
330
331                 public static TOut GetHandlerForObject<TOut>(object obj) where TOut : class, IRegisterable
332                 {
333                         if (s_staticRegistrarStrategy == StaticRegistrarStrategy.None)
334                         {
335                                 // Find hander in internal registrar, that is using reflection (default).
336                                 return Internals.Registrar.Registered.GetHandlerForObject<TOut>(obj);
337                         }
338                         else
339                         {
340                                 // 1. Find hander in static registrar first
341                                 TOut ret = StaticRegistrar.Registered.GetHandlerForObject<TOut>(obj);
342
343                                 // 2. If there is no handler, try to find hander in internal registrar, that is using reflection.
344                                 if (ret == null && s_staticRegistrarStrategy == StaticRegistrarStrategy.All)
345                                 {
346                                         ret = Internals.Registrar.Registered.GetHandlerForObject<TOut>(obj);
347                                 }
348                                 return ret;
349                         }
350                 }
351
352                 public static TOut GetHandlerForObject<TOut>(object obj, params object[] args) where TOut : class, IRegisterable
353                 {
354                         if (s_staticRegistrarStrategy == StaticRegistrarStrategy.None)
355                         {
356                                 // Find hander in internal registrar, that is using reflection (default).
357                                 return Internals.Registrar.Registered.GetHandlerForObject<TOut>(obj, args);
358                         }
359                         else
360                         {
361                                 // 1. Find hander in static registrar first without fallback handler.
362                                 TOut ret = StaticRegistrar.Registered.GetHandlerForObject<TOut>(obj, args);
363
364                                 // 2. If there is no handler, try to find hander in internal registrar, that is using reflection.
365                                 if (ret == null && s_staticRegistrarStrategy == StaticRegistrarStrategy.All)
366                                 {
367                                         ret = StaticRegistrar.Registered.GetHandlerForObject<TOut>(obj, args);
368                                 }
369                                 return ret;
370                         }
371                 }
372
373                 public static void Init(CoreApplication application)
374                 {
375                         Init(application, false);
376                 }
377
378                 public static void Init(CoreApplication application, bool useDeviceIndependentPixel)
379                 {
380                         s_useDeviceIndependentPixel = useDeviceIndependentPixel;
381                         SetupInit(application);
382                 }
383
384                 public static void Init(InitializationOptions options)
385                 {
386                         SetupInit(Context, options);
387                 }
388
389                 static void SetupInit(CoreApplication application, InitializationOptions options = null)
390                 {
391                         Context = application;
392
393                         if (!IsInitialized)
394                         {
395                                 Internals.Log.Listeners.Add(new XamarinLogListener());
396                                 if (System.Threading.SynchronizationContext.Current == null)
397                                 {
398                                         TizenSynchronizationContext.Initialize();
399                                 }
400                                 Elementary.Initialize();
401                                 Elementary.ThemeOverlay();
402                                 Utility.AppendGlobalFontPath(@"/usr/share/fonts");
403
404                                 Device.PlatformServices = new TizenPlatformServices();
405                                 if (Device.info != null)
406                                 {
407                                         ((TizenDeviceInfo)Device.info).Dispose();
408                                         Device.info = null;
409                                 }
410
411                                 Device.Info = new Forms.TizenDeviceInfo();
412                                 Device.SetFlags(s_flags);
413                         }
414                         else if (Device.info != null)
415                         {
416                                 var info = ((TizenDeviceInfo)Device.info).RefreshByDIP();
417                                 ((TizenDeviceInfo)Device.info).Dispose();
418                                 Device.info = info;
419                         }
420
421                         string profile = ((TizenDeviceInfo)Device.Info).Profile;
422                         if (profile == "mobile")
423                         {
424                                 Device.SetIdiom(TargetIdiom.Phone);
425                         }
426                         else if (profile == "tv")
427                         {
428                                 Device.SetIdiom(TargetIdiom.TV);
429                         }
430                         else if (profile == "desktop")
431                         {
432                                 Device.SetIdiom(TargetIdiom.Desktop);
433                         }
434                         else if (profile == "wearable")
435                         {
436                                 Device.SetIdiom(TargetIdiom.Watch);
437                         }
438                         else
439                         {
440                                 Device.SetIdiom(TargetIdiom.Unsupported);
441                         }
442
443                         if (!Forms.IsInitialized && !Forms.IsPreloaded)
444                         {
445                                 StaticRegistrar.RegisterHandlers(CircularUIForms.StaticHandlers);
446                                 CircularUIForms.RegisterDependencyService();
447                                 TizenPlatformServices.AppDomain.CurrentDomain.AddAssembly(Assembly.GetAssembly(typeof(Xamarin.Forms.View)));
448                         }
449
450                         if (!Forms.IsInitialized || Forms.IsPreloaded)
451                         {
452                                 if (options != null)
453                                 {
454                                         s_useDeviceIndependentPixel = options.UseDeviceIndependentPixel;
455                                         s_platformType = options.PlatformType;
456                                         s_useMessagingCenter = options.UseMessagingCenter;
457                                         OptionalFeatureValues.UseStyle = options.UseStyle;
458                                         OptionalFeatureValues.UseShell = options.UseShell;
459                                         OptionalFeatureValues.UseVisual = options.UseVisual;
460
461                                         if (options.Assemblies != null && options.Assemblies.Length > 0)
462                                         {
463                                                 TizenPlatformServices.AppDomain.CurrentDomain.AddAssemblies(options.Assemblies);
464                                         }
465
466                                         // renderers
467                                         if (options.Handlers != null)
468                                         {
469                                                 Internals.Registrar.RegisterRenderers(options.Handlers);
470                                         }
471                                         else
472                                         {
473                                                 // Add Xamarin.Forms.Core assembly by default to apply the styles.
474                                                 if (!Forms.IsPreloaded)
475                                                 {
476                                                         TizenPlatformServices.AppDomain.CurrentDomain.AddAssembly(Assembly.GetAssembly(typeof(Xamarin.Forms.View)));
477                                                 }
478
479                                                 // static registrar
480                                                 if (options.StaticRegistarStrategy != StaticRegistrarStrategy.None)
481                                                 {
482                                                         s_staticRegistrarStrategy = options.StaticRegistarStrategy;
483                                                         StaticRegistrar.RegisterHandlers(options.CustomHandlers);
484
485                                                         if (options.StaticRegistarStrategy == StaticRegistrarStrategy.All)
486                                                         {
487                                                                 Registrar.RegisterAll(new Type[]
488                                                                 {
489                                                                                 typeof(ExportRendererAttribute),
490                                                                                 typeof(ExportImageSourceHandlerAttribute),
491                                                                                 typeof(ExportCellAttribute),
492                                                                                 typeof(ExportHandlerAttribute),
493                                                                                 typeof(ExportFontAttribute)
494                                                                 });
495                                                         }
496                                                 }
497                                                 else
498                                                 {
499                                                         // In .NETCore, AppDomain feature is not supported.
500                                                         // The list of assemblies returned by AppDomain.GetAssemblies() method should be registered manually.
501                                                         // The assembly of the executing application and referenced assemblies of it are added into the list here.
502                                                         TizenPlatformServices.AppDomain.CurrentDomain.RegisterAssemblyRecursively(application.GetType().GetTypeInfo().Assembly);
503
504                                                         Registrar.RegisterAll(new Type[]
505                                                         {
506                                                                 typeof(ExportRendererAttribute),
507                                                                 typeof(ExportImageSourceHandlerAttribute),
508                                                                 typeof(ExportCellAttribute),
509                                                                 typeof(ExportHandlerAttribute),
510                                                                 typeof(ExportFontAttribute)
511                                                         });
512                                                 }
513                                         }
514
515                                         // effects
516                                         var effectScopes = options.EffectScopes;
517                                         if (effectScopes != null)
518                                         {
519                                                 for (var i = 0; i < effectScopes.Length; i++)
520                                                 {
521                                                         var effectScope = effectScopes[i];
522                                                         Internals.Registrar.RegisterEffects(effectScope.Name, effectScope.Effects);
523                                                 }
524                                         }
525
526                                         // css
527                                         var flags = options.Flags;
528                                         var noCss = (flags & InitializationFlags.DisableCss) != 0;
529                                         if (!noCss)
530                                                 Internals.Registrar.RegisterStylesheets();
531                                 }
532                                 else
533                                 {
534                                         // In .NETCore, AppDomain feature is not supported.
535                                         // The list of assemblies returned by AppDomain.GetAssemblies() method should be registered manually.
536                                         // The assembly of the executing application and referenced assemblies of it are added into the list here.
537                                         TizenPlatformServices.AppDomain.CurrentDomain.RegisterAssemblyRecursively(application.GetType().GetTypeInfo().Assembly);
538
539                                         Registrar.RegisterAll(new Type[]
540                                         {
541                                                 typeof(ExportRendererAttribute),
542                                                 typeof(ExportImageSourceHandlerAttribute),
543                                                 typeof(ExportCellAttribute),
544                                                 typeof(ExportHandlerAttribute),
545                                                 typeof(ExportFontAttribute)
546                                         });
547                                 }
548                         }
549
550                         Color.SetAccent(GetAccentColor(profile));
551                         ExpressionSearch.Default = new TizenExpressionSearch();
552                         IsInitialized = true;
553                 }
554
555                 static Color GetAccentColor(string profile)
556                 {
557                         // On Windows Phone, this is the complementary color chosen by the user.
558                         // Good Windows Phone applications use this as part of their styling to provide a native look and feel.
559                         // On iOS and Android this instance is set to a contrasting color that is visible on the default
560                         // background but is not the same as the default text color.
561
562                         switch (profile)
563                         {
564                                 case "mobile":
565                                         // [Tizen_3.0]Basic_Interaction_GUI_[REF].xlsx Theme 001 (Default) 1st HSB: 188 70 80
566                                         return Color.FromRgba(61, 185, 204, 255);
567                                 case "tv":
568                                         return Color.FromRgba(15, 15, 15, 230);
569                                 case "wearable":
570                                         // Theme A (Default) 1st HSB: 207 75 16
571                                         return Color.FromRgba(10, 27, 41, 255);
572                                 default:
573                                         return Color.Black;
574                         }
575                 }
576
577                 /// <summary>
578                 /// Converts the dp into pixel considering current DPI value.
579                 /// </summary>
580                 /// <remarks>
581                 /// Use this API if you want to get pixel size without scaling factor.
582                 /// </remarks>
583                 /// <param name="dp"></param>
584                 /// <returns></returns>
585                 public static int ConvertToPixel(double dp)
586                 {
587                         return (int)Math.Round(dp * s_dpi.Value / 160.0);
588                 }
589
590                 /// <summary>
591                 /// Converts the dp into pixel by using scaling factor.
592                 /// </summary>
593                 /// <remarks>
594                 /// Use this API if you want to get pixel size from dp by using scaling factor.
595                 /// If the scaling factor is 1.0 by user setting, the same value is returned. This is mean that user doesn't want to pixel independent metric.
596                 /// </remarks>
597                 /// <param name="dp"></param>
598                 /// <returns></returns>
599                 public static int ConvertToScaledPixel(double dp)
600                 {
601                         return (int)Math.Round(dp * Device.Info.ScalingFactor);
602                 }
603
604                 /// <summary>
605                 /// Converts the pixel into dp value by using scaling factor.
606                 /// </summary>
607                 /// <remarks>
608                 /// If the scaling factor is 1.0 by user setting, the same value is returned. This is mean that user doesn't want to pixel independent metric.
609                 /// </remarks>
610                 /// <param name="pixel"></param>
611                 /// <returns></returns>
612                 public static double ConvertToScaledDP(int pixel)
613                 {
614                         return pixel / Device.Info.ScalingFactor;
615                 }
616
617                 /// <summary>
618                 /// Converts the pixel into dp value by using scaling factor.
619                 /// </summary>
620                 /// <remarks>
621                 /// If the scaling factor is 1.0 by user setting, the same value is returned. This is mean that user doesn't want to pixel independent metric.
622                 /// </remarks>
623                 /// <param name="pixel"></param>
624                 /// <returns></returns>
625                 public static double ConvertToScaledDP(double pixel)
626                 {
627                         return pixel / Device.Info.ScalingFactor;
628                 }
629
630                 /// <summary>
631                 /// Converts the sp into EFL's font size metric (EFL point).
632                 /// </summary>
633                 /// <param name="sp"></param>
634                 /// <returns></returns>
635                 public static int ConvertToEflFontPoint(double sp)
636                 {
637                         return (int)Math.Round(sp * s_elmScale.Value);
638                 }
639
640                 /// <summary>
641                 /// Convert the EFL's point into sp.
642                 /// </summary>
643                 /// <param name="eflPt"></param>
644                 /// <returns></returns>
645                 public static double ConvertToDPFont(int eflPt)
646                 {
647                         return eflPt / s_elmScale.Value;
648                 }
649
650                 /// <summary>
651                 /// Get the EFL's profile
652                 /// </summary>
653                 /// <returns></returns>
654                 public static string GetProfile()
655                 {
656                         return s_profile.Value;
657                 }
658
659                 // for internal use only
660                 [EditorBrowsable(EditorBrowsableState.Never)]
661                 public static EvasObject Preload()
662                 {
663                         var dummyApp = new DummyFormsApplication();
664                         Init(dummyApp, false);
665                         IsPreloaded = true;
666
667                         EWindow eWindow = null;
668                         ELayout eLayout = null;
669                         CircleSurface eCircleSurface = null;
670                         var typeWin = typeof(EWindow);
671                         var methodInfo = typeWin.GetMethod("CreateWindow", BindingFlags.NonPublic | BindingFlags.Static);
672                         if (methodInfo != null)
673                         {
674                                 eWindow = (EWindow)methodInfo.Invoke(null, new object[] { "FormsWindow" });
675                                 eLayout = (ELayout)eWindow.GetType().GetProperty("BaseLayout")?.GetValue(eWindow);
676                                 eCircleSurface = (CircleSurface)eWindow.GetType().GetProperty("BaseCircleSurface")?.GetValue(eWindow);
677                         }
678
679                         PreloadedWindow preloadedWindow = null;
680                         if (eWindow != null && eLayout != null)
681                         {
682                                 preloadedWindow = new PreloadedWindow(eWindow, eLayout, eCircleSurface);
683                         }
684                         else
685                         {
686                                 preloadedWindow = new PreloadedWindow();
687                         }
688
689                         var locale = TSystemSetting.LocaleLanguage;
690                         TSystemSetting.LocaleLanguageChanged += DummyHandler;
691                         TSystemSetting.LocaleLanguageChanged -= DummyHandler;
692                         void DummyHandler(object sender, System.EventArgs e) { }
693
694                         var types = new[]
695                         {
696                                 typeof(Application),
697                                 typeof(ContentPage),
698                                 typeof(NavigationPage),
699                                 typeof(Shell),
700                                 typeof(ContentPresenter),
701                                 typeof(ContentView),
702                                 typeof(ScrollView),
703                                 typeof(Frame),
704                                 typeof(TemplatedView),
705                                 typeof(StackLayout),
706                                 typeof(AbsoluteLayout),
707                                 typeof(RelativeLayout),
708                                 typeof(Grid),
709                                 typeof(FlexLayout),
710                                 typeof(Image),
711                                 typeof(Label),
712                                 typeof(BoxView),
713                                 typeof(Button),
714                                 typeof(ImageButton),
715                                 typeof(CheckBox),
716                                 typeof(Slider),
717                                 typeof(Stepper),
718                                 typeof(Switch),
719                                 typeof(DatePicker),
720                                 typeof(TimePicker),
721                                 typeof(Entry),
722                                 typeof(Editor),
723                                 typeof(ActivityIndicator),
724                                 typeof(ProgressBar),
725                                 typeof(CarouselView),
726                                 typeof(CollectionView),
727                                 typeof(ListView),
728                                 typeof(Picker),
729                                 typeof(TableView),
730                                 typeof(TextCell),
731                                 typeof(ImageCell),
732                                 typeof(SwitchCell),
733                                 typeof(EntryCell),
734                                 typeof(VisualElement),
735                                 typeof(Page),
736                                 typeof(View),
737                                 typeof(Element),
738                                 typeof(NavigableElement),
739                                 typeof(Layout),
740                                 typeof(Span),
741                                 typeof(TapGestureRecognizer),
742                                 typeof(PropertyCondition),
743                                 typeof(RefreshView),
744                                 typeof(StructuredItemsView),
745                                 typeof(SearchHandler),
746                         };
747
748                         foreach (var type in types)
749                         {
750                                 System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(type.TypeHandle);
751                         }
752                         global::Xamarin.Forms.Platform.Tizen.Native.NativeFactory.PrecreateNatives(preloadedWindow.Window);
753                         global::Tizen.Wearable.CircularUI.Forms.CircularUIForms.Preload(preloadedWindow.Window);
754
755                         return preloadedWindow.Window;
756                 }
757         }
758
759         class TizenExpressionSearch : ExpressionVisitor, IExpressionSearch
760         {
761                 List<object> _results;
762                 Type _targetType;
763
764                 public List<T> FindObjects<T>(Expression expression) where T : class
765                 {
766                         _results = new List<object>();
767                         _targetType = typeof(T);
768                         Visit(expression);
769                         return _results.Select(o => o as T).ToList();
770                 }
771
772                 protected override Expression VisitMember(MemberExpression node)
773                 {
774                         if (node.Expression is ConstantExpression && node.Member is FieldInfo)
775                         {
776                                 var container = ((ConstantExpression)node.Expression).Value;
777                                 var value = ((FieldInfo)node.Member).GetValue(container);
778
779                                 if (_targetType.IsInstanceOfType(value))
780                                         _results.Add(value);
781                         }
782                         return base.VisitMember(node);
783                 }
784         }
785
786         class DummyFormsApplication : FormsApplication { }
787 }