From 7831908665a20bc904217edfbdbb7e40343ff2bd Mon Sep 17 00:00:00 2001 From: Cho Woong Suk Date: Thu, 8 Dec 2016 22:10:16 +0900 Subject: [PATCH 01/16] generate ni file for dotnet-launcher for nitool --system command Change-Id: I6b2f15085b2e63f11951d0ba3e67e271bacfc77e --- NativeLauncher/installer-plugin/common.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NativeLauncher/installer-plugin/common.cc b/NativeLauncher/installer-plugin/common.cc index d4d007f..377fab9 100644 --- a/NativeLauncher/installer-plugin/common.cc +++ b/NativeLauncher/installer-plugin/common.cc @@ -71,10 +71,10 @@ void create_ni_platform() smack_(nicorlib.c_str()); } - const char* platform_dirs[] = {RuntimeDir, DeviceAPIDir}; + const char* platform_dirs[] = {RuntimeDir, DeviceAPIDir, "/usr/bin"}; const char* ignores[] = {corlib.c_str()}; - create_ni_under_dirs(platform_dirs, 2, ignores, 1, [](const char* ni){ + create_ni_under_dirs(platform_dirs, 3, ignores, 1, [](const char* ni){ smack_(ni); }); } -- 2.7.4 From 41189edf30c5be8a7db7930111d268cc31f7345f Mon Sep 17 00:00:00 2001 From: Cho Woong Suk Date: Thu, 8 Dec 2016 22:08:59 +0900 Subject: [PATCH 02/16] bug-fix : load app ni dll file Change-Id: Iaf03cfb5893bf5ace992c48cbc96756dbdf3f814 --- Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) mode change 100644 => 100755 Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs diff --git a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs old mode 100644 new mode 100755 index 693877f..cbb0095 --- a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs +++ b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs @@ -68,7 +68,13 @@ namespace Tizen.Runtime.Coreclr { foreach (string dir in DllDirectories) { - FileInfo f = new FileInfo(Path.Combine(dir, $"{assemblyName.Name}.dll")); + FileInfo f = new FileInfo(Path.Combine(dir, $"{assemblyName.Name}.ni.dll")); + if (File.Exists(f.FullName)) + { + asm = LoadFromNativeImagePath(f.FullName, null); + break; + } + f = new FileInfo(Path.Combine(dir, $"{assemblyName.Name}.dll")); if (File.Exists(f.FullName)) { asm = LoadFromAssemblyPath(f.FullName); -- 2.7.4 From fc168cf98012b338709f2a80bf11fe24d34f6903 Mon Sep 17 00:00:00 2001 From: JongHeon Choi Date: Wed, 14 Dec 2016 17:10:14 +0900 Subject: [PATCH 03/16] Exclude arm64 and i586 architecture Change-Id: I52410a37cdb4dacf5c3789c23d0a0b5211e88a5b --- packaging/dotnet-launcher.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packaging/dotnet-launcher.spec b/packaging/dotnet-launcher.spec index 87cef0e..7e12b6e 100644 --- a/packaging/dotnet-launcher.spec +++ b/packaging/dotnet-launcher.spec @@ -38,6 +38,8 @@ Requires(preun): /usr/bin/systemctl %define _preload_dir /opt/usr/share/dotnet.tizen/preload %define _install_plugin_dir /usr/etc/package-manager/parserlib +ExcludeArch: %{ix86} aarch64 + %description Launchpad plugin for launching dotnet apps -- 2.7.4 From 98afe6369fccef9715458cc954f3b408c83bd572 Mon Sep 17 00:00:00 2001 From: Cho Woong Suk Date: Fri, 16 Dec 2016 15:10:10 +0900 Subject: [PATCH 04/16] bug-fix: do not pre-create bg and conformant. Change-Id: I27cc5e44c72656f87eca5ef94f3c722c20254990 --- NativeLauncher/launcher/launcher.cc | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/NativeLauncher/launcher/launcher.cc b/NativeLauncher/launcher/launcher.cc index c26b0e0..c2d1ce4 100644 --- a/NativeLauncher/launcher/launcher.cc +++ b/NativeLauncher/launcher/launcher.cc @@ -171,26 +171,6 @@ static void PreloadLibsAndWindow(bundle *extra, int type, void *user_data) } elm_win_precreated_object_set(__win); - - __bg = elm_bg_add(__win); - if (__bg) { - evas_object_size_hint_weight_set(__bg, EVAS_HINT_EXPAND, - EVAS_HINT_EXPAND); - elm_win_resize_object_add(__win, __bg); - elm_bg_precreated_object_set(__bg); - } else { - _DBG("[candidate] elm_bg_add() failed"); - } - - __conform = elm_conformant_add(__win); - if (__conform) { - evas_object_size_hint_weight_set(__conform, EVAS_HINT_EXPAND, - EVAS_HINT_EXPAND); - elm_win_resize_object_add(__win, __conform); - elm_conformant_precreated_object_set(__conform); - } else { - _DBG("elm_conformant_add() failed"); - } } void LaunchpadAdapterImpl::LoaderMain(int argc, char* argv[]) -- 2.7.4 From 095697508a12bc9c471e096fdbd0a2e2b0b8f458 Mon Sep 17 00:00:00 2001 From: Pawel Andruszkiewicz Date: Fri, 9 Dec 2016 08:52:45 +0100 Subject: [PATCH 05/16] AssemblyLoader should assist in loading all assemblies The Resolving event from the AssemblyLoadContext is invoked each time it fails to load an assembly. The default AssemblyLoadContext is used internally i.e. when Assembly.Load() or Type.GetType(string) methods are called. Registering for the Resolving event from the default AssemblyLoadContext helps handling the unresolved assemblies and fixes XAML-related issues in Xamarin. TASK=TNET-136 TASK=TCAPI-1863 Change-Id: I0f5f4c2925829eac448a6184a3e19dbde5c1dfc0 Signed-off-by: Pawel Andruszkiewicz --- .../Tizen.Runtime.Coreclr/AssemblyLoader.cs | 89 +++++++++++++++------- .../Tizen.Runtime.Coreclr/AssemblyManager.cs | 24 ++---- 2 files changed, 69 insertions(+), 44 deletions(-) diff --git a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs index cbb0095..35a8ddf 100755 --- a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs +++ b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyLoader.cs @@ -16,6 +16,7 @@ using System; using System.IO; +using System.Linq; using System.Reflection; using System.Runtime.Loader; using System.Collections.Generic; @@ -24,9 +25,24 @@ namespace Tizen.Runtime.Coreclr { public class AssemblyLoader : AssemblyLoadContext { + private const string NativeAssemblyInfix = ".ni"; + + private const string DllAssemblySuffix = ".dll"; + + private const string NativeDllAssemblySuffix = NativeAssemblyInfix + DllAssemblySuffix; + + private static readonly string[] s_suffixes = new string[] { NativeDllAssemblySuffix, DllAssemblySuffix }; + private SortedSet _dllDirectories = new SortedSet(); private SortedSet _nativeDirectories = new SortedSet(); + private HashSet _dllCache = new HashSet(); + + public AssemblyLoader() + { + AssemblyLoadContext.Default.Resolving += OnResolving; + } + public IEnumerable DllDirectories { get { return _dllDirectories; } @@ -43,6 +59,16 @@ namespace Tizen.Runtime.Coreclr { _dllDirectories.Add(directory); _nativeDirectories.Add(directory); + + foreach (var file in Directory.GetFiles(directory)) + { + var info = new FileInfo(file); + + if (info.Extension == DllAssemblySuffix) + { + _dllCache.Add(info); + } + } } } @@ -50,39 +76,30 @@ namespace Tizen.Runtime.Coreclr { _dllDirectories.Remove(directory); _nativeDirectories.Remove(directory); + + _dllCache.RemoveWhere(x => x.DirectoryName == directory); } - protected override Assembly Load(AssemblyName assemblyName) + public Assembly LoadFromPath(string path) { - Assembly asm = null; - - try + if (0 == string.Compare(path, // strA + path.Length - NativeDllAssemblySuffix.Length, // indexA + NativeAssemblyInfix, // strB + 0, // indexB + NativeAssemblyInfix.Length, // length + StringComparison.OrdinalIgnoreCase)) // options { - //asm = AssemblyLoadContext.Default.Load(assemblyName); - asm = AssemblyLoadContext.Default.LoadFromAssemblyName(assemblyName); + return LoadFromNativeImagePath(path, null); } - catch (Exception ex) - when (ex is FileNotFoundException || - ex is BadImageFormatException || - ex is FileLoadException) + else { - foreach (string dir in DllDirectories) - { - FileInfo f = new FileInfo(Path.Combine(dir, $"{assemblyName.Name}.ni.dll")); - if (File.Exists(f.FullName)) - { - asm = LoadFromNativeImagePath(f.FullName, null); - break; - } - f = new FileInfo(Path.Combine(dir, $"{assemblyName.Name}.dll")); - if (File.Exists(f.FullName)) - { - asm = LoadFromAssemblyPath(f.FullName); - break; - } - } + return LoadFromAssemblyPath(path); } - return asm; + } + + protected override Assembly Load(AssemblyName assemblyName) + { + return Resolve(assemblyName); } protected override IntPtr LoadUnmanagedDll(string unmanagedDllName) @@ -103,5 +120,25 @@ namespace Tizen.Runtime.Coreclr return native; } + + private Assembly Resolve(AssemblyName assemblyName) + { + foreach (string suffix in s_suffixes) + { + var info = _dllCache.FirstOrDefault(x => x.Name == assemblyName.Name + suffix); + + if (info != null) + { + return LoadFromPath(info.FullName); + } + } + + return null; + } + + private Assembly OnResolving(AssemblyLoadContext context, AssemblyName assemblyName) + { + return Resolve(assemblyName); + } } } diff --git a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs index 52297a1..de0b293 100644 --- a/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs +++ b/Tizen.Runtime/Tizen.Runtime.Coreclr/AssemblyManager.cs @@ -146,15 +146,7 @@ namespace Tizen.Runtime.Coreclr ALog.Debug($"preload dll : {s}"); try { - Assembly asm = null; - if (s.EndsWith(".ni.dll", StringComparison.CurrentCultureIgnoreCase)) - { - asm = CurrentAssemblyLoaderContext.LoadFromNativeImagePath(s, null); - } - else - { - asm = CurrentAssemblyLoaderContext.LoadFromAssemblyPath(s); - } + Assembly asm = CurrentAssemblyLoaderContext.LoadFromPath(s); // this works strange, vm can't load types except loaded in here. // so user code spit out not found exception. @@ -195,20 +187,16 @@ namespace Tizen.Runtime.Coreclr FileInfo f = new FileInfo(dllPath); if (File.Exists(f.FullName)) { - Assembly asm = null; - if (0 == string.Compare(f.FullName, f.FullName.Length - 7, ".ni", 0, 3, StringComparison.OrdinalIgnoreCase)) - { - asm = CurrentAssemblyLoaderContext.LoadFromNativeImagePath(f.FullName, null); - } - else - { - asm = CurrentAssemblyLoaderContext.LoadFromAssemblyPath(f.FullName); - } + Assembly asm = CurrentAssemblyLoaderContext.LoadFromPath(f.FullName); if (asm == null) throw new FileNotFoundException($"{f.FullName} is not found"); if (asm.EntryPoint == null) throw new ArgumentException($"{f.FullName} did not have EntryPoint"); asm.EntryPoint.Invoke(null, new object[]{argv}); } + else + { + ALog.Debug($"Requested file does not exist: {dllPath}"); + } } catch (Exception e) { -- 2.7.4 From 8ea5d0a517060f492c1757a4b5e85061f8ca7333 Mon Sep 17 00:00:00 2001 From: Inhwan Lee Date: Thu, 15 Dec 2016 14:27:39 +0900 Subject: [PATCH 06/16] add test tool for check launching time Change-Id: I4d29972eceb263559135f8ca7c659ffdaefd0c27 --- tools/README | 95 ++++++++++++++++ tools/performance_test.sh | 285 ++++++++++++++++++++++++++++++++++++++++++++++ tools/timestamp.sh | 56 +++++++++ 3 files changed, 436 insertions(+) create mode 100755 tools/README create mode 100755 tools/performance_test.sh create mode 100755 tools/timestamp.sh diff --git a/tools/README b/tools/README new file mode 100755 index 0000000..41e934b --- /dev/null +++ b/tools/README @@ -0,0 +1,95 @@ +README file for performance test of dotnet launcher + + +[*] SUMMARY +------------------------------------------------------------------------------- +Performance test is a tool to calcuate launching time. +This tool is performed on the host where the device is connected with sdb + +[*] PREPARATIONS +------------------------------------------------------------------------------- +The test consists of two files. + - performance_test.sh : main executable script + - timestamp.sh : used by "performance_test.sh" +The files should be in the same directory in host. + +For running automatic test, you have to locate ".tpk" files in specific directory +More detail, it describes in "USAGE" section. + +This test need below package + - inotify-tools +If the package is not exist, it will try to install the package. + +The host can connect device with sdb. + + +[*] TEST MODES +------------------------------------------------------------------------------- +There are two modes in performance test + - auto test mode + - manual test mode + +Each mode has the following characteristics. +[Auto test mode] + This mode automatically installs applications and measures and records performance. + This mode need ".tpk" packaged dotnet application. It should located in "tpk" directory. + So, files locates likes below. + . + ├── performance_test.sh + ├── README + ├── timestamp.sh + └── tpk + └── .tpk + There can be several tpk files. And tpk files can be freely added or deleted by the user. +[Manual test mode] + This mode measures the execution time when the user executes the installed applications. + After executing this mode, the user runs and terminates the application. + And then, result of launching time and making report file. + + +[*] USAGE +------------------------------------------------------------------------------- +The test has two modes. + - automatic test + - manual test + +Each test can be run through shell below options. + -a --auto : execute automatic test + -m --manual : execute manual test + +In the auto test mode does not require user input. +In the manual test mode, the user executes / terminates the application after executing the test. + + +[*] TEST RESULT +------------------------------------------------------------------------------- +Test results are generated as files in the "result/" directory. +The resulting file name is determined by the date and time, likes "result/result_YYYYMMDD_HHmm.log" + +Test results consist of launching time(ms) and applicatoin id. +example of result : + T(ms) APP ID + 680 org.tizen.example.BasicSampleXamarine.Tizen + 710 org.tizen.example.XamarinApplication1.Tizen + 1460 org.tizen.example.EmailUI.Tizen + 770 org.tizen.example.FormsTizenGallery.Tizen + 2390 org.tizen.example.SNSUI.Tizen + + +[*] ERROR CASE +------------------------------------------------------------------------------- +Some system can be occur error with some points. +In this section, we would like to share some solutions to solve the problems. + +[>] Inotify-tools - 'max_user_watchers' error + + [ERROR CASE] + Failed to watch stream.log; upper limit on inotify watches reached! + Please increase the amount of inotify watches allowed per user via `/proc/sys/fs/inotify/max_user_watches'. + + execute below command for expand max_user_watchers for inotify-tool + + [SOLVE] + echo 32768 | sudo tee /proc/sys/fs/inotify/max_user_watches + echo fs.inotify.max_user_watches=32768 | sudo tee -a /etc/sysctl.conf + sudo sysctl -p diff --git a/tools/performance_test.sh b/tools/performance_test.sh new file mode 100755 index 0000000..def3105 --- /dev/null +++ b/tools/performance_test.sh @@ -0,0 +1,285 @@ +#!/bin/bash + +STREAM_LOG_FILE=stream.log +DATE=$(date +%Y%m%d_%H%M) +RESULT_LOG_FILE='result/result_'$DATE'.log' + +WAIT_FOR_LAUNCH=10 +WAIT_FOR_KILL=5 + +PKG_IDS=() +APP_IDS=() + +initialize () +{ + echo "" + echo "[>] Initialize for Performance Test" + if [ $(sdb get-state 2>/dev/null | grep -c "device") -eq 0 ]; + then + echo "" + echo "[!] device is not connected - cannot execute" + echo "" + exit 0 + fi + + if [ $(dpkg-query -W -f='${Status}' inotify-tools 2>/dev/null | grep -c "ok installed") -eq 0 ]; + then + echo "" + echo "[!] inotify-tools package should install" + echo "[!] starting install inotify-tools .. " + sudo apt-get install inotify-tools + if [ $(dpkg-query -W -f='${Status}' inotify-tools 2>/dev/null | grep -c "ok installed") -eq 0 ]; + then + echo "" + echo "[!] install inotify-tools fail - cannot execute" + echo "" + exit 0 + fi + echo 32768 | sudo tee /proc/sys/fs/inotify/max_user_watches + echo fs.inotify.max_user_watches=32768 | sudo tee -a /etc/sysctl.conf + sudo sysctl -p + fi + sdb root on + sdb shell "devicectl display stop">/dev/null 2>&1 + mkdir result>/dev/null 2>&1 + rm $STREAM_LOG_FILE>/dev/null 2>&1 + touch $STREAM_LOG_FILE +} + +install_tpk () +{ +#install tpk packages + echo "[>] Installing package in tpk directory" + TPKS=($(ls tpk | grep .tpk)) + + + for item in ${TPKS[*]} + do + INSTALL_MSG=$(sdb install tpk/$item | grep start) + INSTALL_MSG=$(echo $INSTALL_MSG | sed "s/\[/ /g") + INSTALL_MSG=$(echo $INSTALL_MSG | sed "s/\]/ /g") + PKG_IDS+=($(echo $INSTALL_MSG | awk '{print $7}')) + echo " [>] ($(echo $INSTALL_MSG | awk '{print $7}')) installs complete" + done +} + +get_current_tpk_apps () +{ + echo "[>] Get application list in device" + PKG_IDS+=$( + sdb shell "su - owner -c 'pkgcmd -l | grep tpk'" | while read line + do + APP_LIST_ENTITY=$line + APP_LIST_ENTITY=$(echo $APP_LIST_ENTITY | sed "s/\[/ /g") + APP_LIST_ENTITY=$(echo $APP_LIST_ENTITY | sed "s/\]/ /g") + APP_OWNER=($(echo $APP_LIST_ENTITY | awk '{print $1}')) + if [[ $APP_OWNER == 'user' ]] + then + echo $APP_LIST_ENTITY | awk '{print $6}' + fi + done | sort + ) +} + +make_appid_list () +{ +#get app ids + echo "[>] Get application id that installed" + for item in ${PKG_IDS[*]} + do + APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -l | grep $item'") + APP_LIST_MSG=${APP_LIST_MSG#*\'} + APP_LIST_MSG=$(echo $APP_LIST_MSG | sed "s/'/ /g") + APP_IDS+=($(echo $APP_LIST_MSG | awk '{print $2}')) + done +} + +initialize_first_launch () +{ + if [[ -z ${APP_IDS[0]} ]]; then + echo "" + echo "[!] No tpk Packages for test" + echo "[!] Copy tpk files in [./tpk] directory" + echo "" + exit 0 + fi + echo "[>] Initial launch an application" + APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -s ${APP_IDS[0]}'") + sleep 10 + APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -k ${APP_IDS[0]}'") + sleep 5 +} + +execute_time_stamp_auto () +{ + echo "" + echo "[>] Start performance test that applciation launching " + echo "" +#execute dlogstreamer + sdb shell "dlogutil -c" + sdb shell "dlogutil -v time AUL APP_CORE|grep -E 'app_request_to_launchpad_for_uid.*[SECURE_LOG].*launch.*request|__show_cb.*[EVENT_TEST][EVENT]'" >> $STREAM_LOG_FILE & + DLOG_STREAMER_PID=$! +#execute timestamp + /bin/bash ./timestamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE & + TIMESTAMP_PID=$! +} + +execute_time_stamp_manual () +{ +#execute dlogstreamer + echo "" + echo "[>] Start performance test that applciation launching " + echo "" + rm $STREAM_LOG_FILE + touch $STREAM_LOG_FILE + sdb shell "dlogutil -c" + sdb shell "dlogutil -v time AUL APP_CORE|grep -E 'app_request_to_launchpad_for_uid.*[SECURE_LOG].*launch.*request|__show_cb.*[EVENT_TEST][EVENT]'" >> $STREAM_LOG_FILE & + DLOG_STREAMER_PID=$! +#execute timestamp + /bin/bash ./timestamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE + TIMESTAMP_PID=$! + wait $TIMESTAMP_PID +} + +execute_time_stamp_manual_trace () +{ +#execute dlogstreamer + echo "" + echo "[>] Start performance test that applciation launching " + echo "" + rm $STREAM_LOG_FILE + touch $STREAM_LOG_FILE + sdb shell "dlogutil -c" + sdb shell "dlogutil -v time AUL APP_CORE|grep -E 'app_request_to_launchpad_for_uid.*[SECURE_LOG].*launch.*request|__show_cb.*[EVENT_TEST][EVENT]'" >> $STREAM_LOG_FILE & + DLOG_STREAMER_PID=$! +#execute timestamp + /bin/bash ./timestamp.sh $STREAM_LOG_FILE $RESULT_LOG_FILE & + TIMESTAMP_PID=$! +#execute ttrace + ~/tizen-sdk/tools/ttrace/ttrace.py -b 20480 -t 10 -o result/trace.html idle app view am & + TTRACE_PID=$! + wait $TTRACE_PID + rm result/*.ftrace + rm result/*.raw +} + +execute_all_app () +{ +#execute each apps + for item in ${APP_IDS[*]} + do + APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -s $item'") + sleep $WAIT_FOR_LAUNCH + APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -k $item'") + sleep $WAIT_FOR_KILL + done +} + +execute_all_app_trace () +{ +#execute each apps + for item in ${APP_IDS[*]} + do + ~/tizen-sdk/tools/ttrace/ttrace.py -b 20480 -t 13 -o result/${item}.html idle app view am & > /dev/null 2>&1 + TTRACE_PID=$! + sleep 1 + APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -s $item'") + sleep $WAIT_FOR_LAUNCH + APP_LIST_MSG=$(sdb shell "su - owner -c 'app_launcher -t $item'") + sleep $WAIT_FOR_KILL + sleep 4 + done + rm result/*.ftrace + rm result/*.raw +} + +finalize () +{ + echo "" + echo "[>] Result" + echo "" + cat $RESULT_LOG_FILE + echo "" + echo "[>] Result file : [ $RESULT_LOG_FILE ]" +} + +destory () +{ + echo "" + kill -9 $DLOG_STREAMER_PID>/dev/null 2>&1 + kill -9 $TIMESTAMP_PID>/dev/null 2>&1 + kill -9 $TTRACE_PID>/dev/null 2>&1 + rm $STREAM_LOG_FILE>/dev/null 2>&1 + sdb shell "devicectl display start">/dev/null 2>&1 + echo "[>] Finalize for Performance Test" + echo "" +} + +help () +{ + echo "" + echo "[!] usage :