diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a678cbd --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +# top-most EditorConfig file +root = true + +[*] +end_of_line = lf +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..485dee6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5cf3b92 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,65 @@ +FROM ubuntu:18.04 + +# Install prerequisites +RUN apt-get update && apt-get install -y \ + ca-certificates \ + wget \ + zip \ + unzip \ + pciutils \ + locales \ + libssl1.0.0 \ + # helper packages + curl \ + sudo \ + net-tools \ + nano \ + && rm -rf /var/lib/apt/lists/* + +# Set the locale +# see: https://stackoverflow.com/questions/28405902/how-to-set-the-locale-inside-a-debian-ubuntu-docker-container +RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 + +# Add a user +ARG USER=developer +ARG PASSWORD=developer +RUN useradd --create-home --shell /bin/bash ${USER} \ + && echo "${USER}:${PASSWORD}" | chpasswd +ENV HOME /home/${USER} + +# Allow sudo without password +# See: https://stackoverflow.com/questions/8784761/adding-users-to-sudoers-through-shell-script/8784846 +RUN echo "${USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers + +USER ${USER} +WORKDIR ${HOME} + +# Remove sudo notice on login +# See: https://askubuntu.com/questions/22607/remove-note-about-sudo-that-appears-when-opening-the-terminal +RUN touch .sudo_as_admin_successful + +# Install tizen studio +# See: https://developer.tizen.org/development/tizen-studio/download/installing-tizen-studio#cli_installer +ARG TIZEN_STUDIO_VERSION=3.7 +ARG TIZEN_STUDIO_FILE=web-cli_Tizen_Studio_${TIZEN_STUDIO_VERSION}_ubuntu-64.bin +RUN wget http://download.tizen.org/sdk/Installer/tizen-studio_${TIZEN_STUDIO_VERSION}/${TIZEN_STUDIO_FILE} \ + && chmod +x ${TIZEN_STUDIO_FILE} \ + && echo y | ./${TIZEN_STUDIO_FILE} --accept-license \ + && rm ${TIZEN_STUDIO_FILE} + +# Copy author certificate and profiles.xml +COPY --chown=${USER} tizen-profile/author.p12 author.p12 +COPY --chown=${USER} tizen-profile/profiles.xml ${HOME}/tizen-studio-data/profile/profiles.xml + +# Copy and extract webOS CLI +COPY vendor/webos_cli_tv.zip . +RUN unzip -q webos_cli_tv.zip -d webOS_TV_SDK \ + && chmod -R +x webOS_TV_SDK/CLI/bin \ + && rm webos_cli_tv.zip + +# Add tizen/webos cli to PATH +ENV PATH $PATH:$HOME/tizen-studio/tools/:$HOME/tizen-studio/tools/ide/bin/:$HOME/tizen-studio/package-manager/:$HOME/webOS_TV_SDK/CLI/bin + diff --git a/README.md b/README.md new file mode 100644 index 0000000..65854bd --- /dev/null +++ b/README.md @@ -0,0 +1,246 @@ +# docker-tizen-webos-sdk +[Samsung Tizen CLI](https://developer.samsung.com/smarttv/develop/getting-started/using-sdk/command-line-interface.html) +and [LG webOS CLI](http://webostv.developer.lge.com/sdk/tools/using-webos-tv-cli/) bundled as docker container. +Allows to develop, build, launch and debug Smart TV apps without installing Tizen Studio and webOS SDK. +Available CLI commands: +* `tizen` +* `sdb` +* `ares-*` + +## Requirements +* for Mac/Windows - [Docker Desktop](https://www.docker.com/products/docker-desktop) +* for Linux - [Docker Engine](https://docs.docker.com/engine/install/) + +## Usage +Run `bash` session inside container: +``` +docker run -it --rm vitalets/tizen-webos-sdk bash +``` +Now you have Ubuntu with `sdb`, `tizen`, and `ares-*` commands available: +``` +$ tizen version +Tizen CLI 2.5.21 + +$ sdb version +Smart Development Bridge version 4.2.12 + +$ ares-setup-device --version +Version: 1.10.4-j1703-k +``` +### Samsung Tizen TV +#### Get info about Samsung TV +If you have Samsung TV with IP `192.168.1.66` in the same network as your host machine, you can get TV info: +``` +curl http://192.168.1.66:8001/api/v2/ +``` +
+ Example response + + { + "device":{ + "FrameTVSupport":"false", + "GamePadSupport":"true", + "ImeSyncedSupport":"true", + "Language":"ru_RU", + "OS":"Tizen", + "PowerState":"on", + "TokenAuthSupport":"true", + "VoiceSupport":"false", + "WallScreenRatio":"0", + "WallService":"false", + "countryCode":"RU", + "description":"Samsung DTV RCR", + "developerIP":"192.168.1.64", + "developerMode":"1", + "duid":"uuid:88d68ee4-cffc-47c4-894f-6d46ca51333a", + "firmwareVersion":"Unknown", + "id":"uuid:88d68ee4-cffc-47c4-894f-6d46ca51333a", + "ip":"192.168.1.66", + "model":"19_MUSEL_UHD", + "modelName":"UE43RU7400UXRU", + "name":"[TV] Samsung 7 Series (43)", + "networkType":"wireless", + "resolution":"3840x2160", + "smartHubAgreement":"true", + "ssid":"94:4a:0c:86:c7:00", + "type":"Samsung SmartTV", + "udn":"uuid:88d68ee4-cffc-47c4-894f-6d46ca51333a", + "wifiMac":"B8:BC:5B:93:7E:D2" + }, + "id":"uuid:88d68ee4-cffc-47c4-894f-6d46ca51333a", + "isSupport":"{\"DMP_DRM_PLAYREADY\":\"false\",\"DMP_DRM_WIDEVINE\":\"false\",\"DMP_available\":\"true\",\"EDEN_available\":\"true\",\"FrameTVSupport\":\"false\",\"ImeSyncedSupport\":\"true\",\"TokenAuthSupport\":\"true\",\"remote_available\":\"true\",\"remote_fourDirections\":\"true\",\"remote_touchPad\":\"true\",\"remote_voiceControl\":\"false\"}\n", + "name":"[TV] Samsung 7 Series (43)", + "remote":"1.0", + "type":"Samsung SmartTV", + "uri":"http://192.168.1.66:8001/api/v2/", + "version":"2.0.25" + } +
+ +#### Connect to Samsung TV +Please ensure that TV is in [Developer Mode](https://developer.samsung.com/smarttv/develop/getting-started/using-sdk/tv-device.html) +and Developer IP equals to your host IP (check `developerMode` and `developerIP` in curl response). +``` +$ sdb connect 192.168.1.66 + +* Server is not running. Start it now on port 26099 * +* Server has started successfully * +connecting to 192.168.1.66:26101 ... +connected to 192.168.1.66:26101 +``` + +#### List connected TVs +``` +$ sdb devices + +List of devices attached +192.168.1.66:26101 device UE43RU7400UXRU +``` + +#### Get TV capabilities +``` +$ sdb -s 192.168.1.66 capability + +secure_protocol:enabled +intershell_support:disabled +filesync_support:pushpull +... +``` + +#### Get list of installed apps +``` +$ sdb -s 192.168.1.66 shell 0 applist + +Application List for user 5001 +User's Application +Name AppID +================================================= +'HdmiCec' 'org.tizen.hdmicec' +'automation-app' 'org.tizen.automation-app' +... +``` +#### Launch app on TV +``` +$ tizen run -s 192.168.1.66:26101 -p 9Ur5IzDKqV.TizenYouTube + +Launching the Tizen application... +-------------------- +Platform log view +-------------------- +... successfully launched pid = 1656 with debug 0 +Tizen application is successfully launched. +``` +or +``` +$ sdb -s 192.168.1.66:26101 shell 0 was_execute 9Ur5IzDKqV.TizenYouTube +``` + +#### Pack app +Sample developer certificate is included, so you can pack your app without any setup (for development). +Author.p12 / distributor.p12 password is `developer`. +Run container with mounting app source `./src` into `/app`: +``` +docker run -it --rm -v ./src:/app vitalets/tizen-webos-sdk bash +``` +Create `wgt` package: +``` +tizen package -t wgt -o /home/developer -- /app + +The active profile is used for signing. If you want to sign with other profile, please use '--sign' option. +Author certficate: /home/developer/author.p12 +Distributor1 certificate : /home/developer/tizen-studio/tools/certificate-generator/certificates/distributor/tizen-distributor-signer.p12 +Excludes File Pattern: {.manifest.tmp, .delta.lst} +Ignore File: /app/.manifest.tmp +Package File Location: /home/developer/MyTvApp.wgt +``` + +#### Install app +``` +$ tizen install -s 192.168.1.66:26101 --name MyTvApp.wgt -- /home/developer + +Transferring the package... +Transferred the package: /home/developer/MyTvApp.wgt -> /home/owner/share/tmp/sdk_tools/tmp +Installing the package... +-------------------- +Platform log view +-------------------- +install TESTABCDEF.MyTvApp +package_path /home/owner/share/tmp/sdk_tools/tmp/MyTvApp.wgt +was_install_app return WAS_TRUE +app_id[TESTABCDEF.MyTvApp] install start +... +app_id[TESTABCDEF.MyTvApp] install completed +spend time for wascmd is [1898]ms +cmd_ret:0 +Installed the package: Id(TESTABCDEF.MyTvApp) +Tizen application is successfully installed. +Total time: 00:00:02.895 +``` +> You may need to rename wgt before installing +> because `tizen install` does not work properly with spaces and non-latin symbols in wgt filename + +#### Debug app +Launch app in debug mode: +``` +$ sdb -s 192.168.1.66:26101 shell 0 debug TESTABCDEF.MyTvApp + +... successfully launched pid = 12915 with debug 1 port: 34541 +``` +Then open in chrome url `http://{TV_IP}:{PORT}` using port from previous command. + +#### Close app +``` +$ sdb -s 192.168.1.66:26101 shell 0 kill TESTABCDEF +``` +> Note using only `packageId` instead of full `appId`. + +#### Uninstall app +``` +$ tizen uninstall -s 192.168.1.66:26101 -p TESTABCDEF.MyTvApp + +-------------------- +Platform log view +-------------------- +uninstall TESTABCDEF.MyTvApp +app_id[TESTABCDEF.MyTvApp] uninstall start +... +app_id[TESTABCDEF.MyTvApp] uninstall completed +spend time for wascmd is [2027]ms +cmd_ret:0 +Total time: 00:00:02.703 +``` + +#### Pack, install and launch app on TV in single command +App sources are in `./src`. +The following env variables are used: +- `TV_IP=192.168.1.66` +- `APP_ID=TESTABCDEF.MyTvApp` (from config.xml) +- `APP_NAME="My TV App"` (from config.xml) +``` +docker run -it --rm \ + -e TV_IP=192.168.1.66 \ + -e APP_ID=TESTABCDEF.MyTvApp \ + -e APP_NAME="My TV App" \ + -v ./src:/app \ + vitalets/tizen-webos-sdk /bin/bash -c '\ + tizen package -t wgt -o . -- /app \ + && mv "$APP_NAME.wgt" app.wgt \ + && sdb connect $TV_IP \ + && tizen install -s $TV_IP:26101 --name app.wgt -- . \ + && tizen run -s $TV_IP:26101 -p $APP_ID' +``` + +### LG WebOS TV +tbd + +## Development + +#### Build container +```bash +docker build -t vitalets/tizen-webos-sdk . +``` + +#### Publish to Docker Hub +```bash +docker push vitalets/tizen-webos-sdk +``` diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..571e9e7 --- /dev/null +++ b/test.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +cmd() { + echo $(docker run -it --rm vitalets/tizen-webos-sdk $@) | tr -d '\r' +} + +assert() { + local actual="$1" + local expected="$2" + if [ "$actual" == "$expected" ]; then + echo "OK: \"$expected\"" + else + echo "ERROR: \"$actual\" != \"$expected\"" + exit 1 + fi +} + +assert "$(cmd tizen version)" "Tizen CLI 2.5.21" +assert "$(cmd sdb version)" "Smart Development Bridge version 4.2.12" +assert "$(cmd ares-setup-device --version)" "Version: 1.10.4-j1703-k" diff --git a/tizen-profile/author.p12 b/tizen-profile/author.p12 new file mode 100644 index 0000000..228ded1 Binary files /dev/null and b/tizen-profile/author.p12 differ diff --git a/tizen-profile/profiles.xml b/tizen-profile/profiles.xml new file mode 100644 index 0000000..4fbb126 --- /dev/null +++ b/tizen-profile/profiles.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/vendor/webos_cli_tv.zip b/vendor/webos_cli_tv.zip new file mode 100644 index 0000000..356a3a7 Binary files /dev/null and b/vendor/webos_cli_tv.zip differ