[WIP] Profile data generation tools to use in candidate process
authorj-h.choi <j-h.choi@samsung.com>
Mon, 25 Jul 2022 04:35:50 +0000 (13:35 +0900)
committer조웅석/Common Platform Lab(SR)/삼성전자 <ws77.cho@samsung.com>
Wed, 24 Aug 2022 00:39:29 +0000 (09:39 +0900)
Change-Id: If92eaf2089233d65e137cd8c8b8c59f120541de1

tools/CandidateMCJ/candidate_mcj.py [new file with mode: 0755]

diff --git a/tools/CandidateMCJ/candidate_mcj.py b/tools/CandidateMCJ/candidate_mcj.py
new file mode 100755 (executable)
index 0000000..333c93c
--- /dev/null
@@ -0,0 +1,180 @@
+#!/usr/bin/env python3
+
+import subprocess, os, argparse
+
+from time import sleep
+from getpass import getpass
+
+# Default .NET application used in TV
+pre_app_lists = [
+       "com.samsung.tv.csfs",
+       "com.samsung.tv.mycontents",
+       "com.samsung.tv.samsung-health",
+       "com.samsung.tv.searchall",
+       "com.samsung.tv.social-chat-app",
+       "com.samsung.tv.store"]
+
+# Default system module used for candidate process in TV
+pre_system_module_lists = [
+       "System.Private.CoreLib",
+       "Tizen.NUI",
+       "System.Net.Http",
+       "System.Text.Json"]
+
+tizen_profile_data_path = "/home/owner/data/.__tizen_candidate_profile_data"
+
+def cmd(command):
+    return subprocess.run((f"sdb -s {serial_num} " + command).split(), encoding="utf-8", stdout=subprocess.PIPE)
+
+
+def download_mcj_edit():
+    if not os.path.exists("mcj-edit.py"):
+        print("Download mcj-edit.py: Start")
+
+        user_id = input("Username for 'https://github.sec.samsung.net': ")
+        password = getpass(f"Password for 'https://{user_id}@github.sec.samsung.net': ")
+        subprocess.Popen((f"curl -L -O https://raw.github.sec.samsung.net/dotnet/runtime/release/6.0-tizen/src/coreclr/tools/mcj-edit/mcj-edit.py -u {user_id}:{password} -v").split(), encoding="utf-8", stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout
+        sleep(3)
+        with open("mcj-edit.py", 'r') as f:
+            if "404: Not Found" == f.readline():
+                print("\nremote: Invalid username or password.")
+                os.remove("mcj-edit.py")
+                exit(1)
+
+        print("Download mcj-edit.py: End")
+
+
+def get_profile():
+    print("Get profile data: Start")
+
+    for app in app_ids:
+        print(f"Kill appId: {app}")
+        cmd(f"shell app_launcher -t {app}")
+        cmd(f"shell dotnettool --rm-app-profile {app}")
+        sleep(3)
+
+    cmd(f"shell cp {tizen_profile_data_path} {tizen_profile_data_path}.origin")
+    cmd(f"shell rm {tizen_profile_data_path}")
+    cmd(f'shell killall dotnet-hydra-loader dotnet-loader')
+    sleep(30)
+    
+    for app in app_ids:
+        print(f"Launch appId: {app}")
+        cmd(f"shell app_launcher -s {app}")
+        sleep(30)
+        cmd(f"shell app_launcher -t {app}")
+        cmd(f"pull /home/owner/apps_rw/{app}/data/.__tizen_specific_profile_data {app}")
+        sleep(3)
+
+    print("Get profile data: End")
+
+
+def split_profile():
+    print("Split profile data: Start")
+
+    system_module_path = ""
+    with open("system_module", 'w') as f:
+        for module in sys_modules:
+            f.write(module+"\n")
+            print(f"System modules: {module}")
+
+    for app in app_ids:
+        print(f"Split appId: {app}")
+        subprocess.run((f"python3 mcj-edit.py split -i {app} --system-modules-list system_module").split(), encoding="utf-8", stdout=subprocess.PIPE)
+        sleep(3)
+
+    os.remove("system_module")
+
+    print("Split profile data: End")
+
+
+def set_profile():
+    cmd(f"shell chsmack -a User::App::Shared {tizen_profile_data_path}")
+    cmd(f"shell chown owner:users {tizen_profile_data_path}")
+    cmd(f"shell chmod 644 {tizen_profile_data_path}")
+    cmd(f"shell rm {tizen_profile_data_path}.origin")
+    os.remove("mcj-edit.py")
+
+    for app in app_ids:
+        subprocess.run((f"rm {app}").split(), encoding="utf-8", stdout=subprocess.PIPE)
+        subprocess.run((f"rm {app}.app").split(), encoding="utf-8", stdout=subprocess.PIPE)
+        subprocess.run((f"rm {app}.sys").split(), encoding="utf-8", stdout=subprocess.PIPE)
+
+
+def merge_profile():
+    print("Merge profile data: Start")
+
+    app_sys_lists = ""
+    for app in app_ids:
+        app_sys_lists += f"-i {app}.sys "
+
+    subprocess.run((f"python3 mcj-edit.py merge " + app_sys_lists + "-o .__tizen_candidate_profile_data").split(), encoding="utf-8", stdout=subprocess.PIPE)
+    sleep(3)
+
+    print("Merge profile data: End")
+
+    if not os.path.exists(f".__tizen_candidate_profile_data"):
+        cmd(f"shell cp {tizen_profile_data_path}.origin {tizen_profile_data_path}")
+        set_profile()
+        print("Candidate profile data generation: FAIL")
+        exit(1)
+    else:
+        cmd(f"push .__tizen_candidate_profile_data /home/owner/data/")
+        set_profile()
+        print("Candidate profile data generation: SUCCESS")
+
+
+def read_serial():
+    global serial_num
+
+    raw = subprocess.run(("sdb devices").split(), encoding="utf-8", stdout=subprocess.PIPE).stdout
+    lines = [l for l in raw.splitlines() if not l.startswith("* ")]
+    if len(lines) <= 1:
+        serial_num = None
+    elif len(lines) == 2:
+        serial_num = lines[1].split("  ")[0].split(":")[0].strip()
+    else:
+        serials = []
+        for idx in range(1, len(lines)):
+            serial = lines[idx].split("        ")[0].split(":")[0].replace("device", "").strip()
+            serials.append(serial)
+            print(f"[{idx}] {serial} - {lines[idx].split('     ')[2].strip()}")
+        choice = input(f"Select a device [1-{len(lines) - 1}]: ")
+        serial_num = serials[int(choice) - 1].strip() if choice.isdigit() else None
+    return serial_num
+
+
+def main():
+    epilog = \
+   '''Reference link :
+   https://github.sec.samsung.net/dotnet/runtime/blob/release/6.0-tizen/src/coreclr/tools/mcj-edit/README.md
+   '''
+
+    global app_ids, sys_modules
+
+    parser = argparse.ArgumentParser(description="Profile data generation tools to use in candidate process", epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter)
+    parser.add_argument("-a", metavar="APP_ID", nargs="*", type=str, help='target app ids (default: predefined 6 applications)', default=pre_app_lists)
+    parser.add_argument("-s", metavar="SYS_MODULE", nargs="*", type=str, help='system module lists (default: predefined 4 system modules)', default=pre_system_module_lists)
+    args = parser.parse_args()
+    app_ids = args.a
+    sys_modules = args.s
+
+    serial = read_serial()
+    if serial is None:
+        print("No connected device(s).")
+        exit(1)
+
+    cmd(f"root on")
+    cmd(f"shell mount -o remount,rw /")
+
+    download_mcj_edit();
+    get_profile()
+    split_profile()
+    merge_profile()
+
+
+if __name__ == "__main__":
+    try:
+        main()
+    except KeyboardInterrupt:
+        exit(1)