├── .gitignore ├── .dockerignore ├── tizen-profile ├── author.p12 └── profiles.xml ├── .editorconfig ├── test.sh ├── Dockerfile └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | .vscode 4 | 5 | /vendor 6 | /todo.txt 7 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | .idea 3 | .editorconfig 4 | 5 | test.sh 6 | /vendor/web-cli_Tizen_Studio_* 7 | -------------------------------------------------------------------------------- /tizen-profile/author.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vitalets/docker-tizen-webos-sdk/HEAD/tizen-profile/author.p12 -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # top-most EditorConfig file 2 | root = true 3 | 4 | [*] 5 | end_of_line = lf 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | -------------------------------------------------------------------------------- /tizen-profile/profiles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cmd() { 4 | echo $(docker run -it --rm --platform linux/amd64 -v /home/developer vitalets/tizen-webos-sdk $@) | tr -d '\r' 5 | } 6 | 7 | assert() { 8 | local actual="$1" 9 | local expected="$2" 10 | if [ "$actual" == "$expected" ]; then 11 | echo "OK: \"$expected\"" 12 | else 13 | echo "ERROR: \"$actual\" != \"$expected\"" 14 | exit 1 15 | fi 16 | } 17 | 18 | assert "$(cmd tizen version)" "Tizen CLI 2.5.25" 19 | assert "$(cmd sdb version)" "Smart Development Bridge version 4.2.25" 20 | assert "$(cmd ares -V)" "webOS TV CLI Version: 1.12.4-j27" 21 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=linux/amd64 ubuntu:22.04 2 | 3 | # Install prerequisites 4 | RUN apt-get update && apt-get install -y \ 5 | ca-certificates \ 6 | wget \ 7 | zip \ 8 | unzip \ 9 | pciutils \ 10 | locales \ 11 | libssl-dev \ 12 | # helper packages 13 | curl \ 14 | net-tools \ 15 | nano \ 16 | && rm -rf /var/lib/apt/lists/* 17 | 18 | # Set the locale 19 | # see: https://stackoverflow.com/questions/28405902/how-to-set-the-locale-inside-a-debian-ubuntu-docker-container 20 | RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen 21 | ENV LANG en_US.UTF-8 22 | ENV LANGUAGE en_US:en 23 | ENV LC_ALL en_US.UTF-8 24 | 25 | # Add a user 26 | ARG USER=developer 27 | RUN useradd --create-home ${USER} 28 | ENV HOME /home/${USER} 29 | 30 | USER ${USER} 31 | WORKDIR ${HOME} 32 | 33 | # Install tizen studio 34 | # See: https://developer.tizen.org/development/tizen-studio/download/installing-tizen-studio#cli_installer 35 | # Tizen Studio can't be installed under root, so we use developer. 36 | # Tizen Studio must be installed in user home dir. 37 | # See: https://stackoverflow.com/questions/47269478/error-installing-tizen-studio-on-windows-10 38 | # See also: https://forum.developer.samsung.com/t/double-click-on-installer-tizen-studio-4-1-doesnt-launch-the-app-on-big-sure-11-3-1/13352/8 39 | ARG TIZEN_STUDIO_VERSION=5.5 40 | ARG TIZEN_STUDIO_FILE=web-cli_Tizen_Studio_${TIZEN_STUDIO_VERSION}_ubuntu-64.bin 41 | ARG TIZEN_STUDIO_URL=http://download.tizen.org/sdk/Installer/tizen-studio_${TIZEN_STUDIO_VERSION}/${TIZEN_STUDIO_FILE} 42 | RUN wget ${TIZEN_STUDIO_URL} \ 43 | && chmod +x ${TIZEN_STUDIO_FILE} \ 44 | && echo y | ./${TIZEN_STUDIO_FILE} --accept-license \ 45 | && rm ${TIZEN_STUDIO_FILE} 46 | 47 | # Copy sample author certificate and profiles.xml 48 | COPY --chown=${USER} tizen-profile/author.p12 author.p12 49 | COPY --chown=${USER} tizen-profile/profiles.xml ${HOME}/tizen-studio-data/profile/profiles.xml 50 | 51 | # Container is intentionally started under the root user. 52 | # Starting under non-root user will cause permissions issue when attaching volumes 53 | # See: https://github.com/moby/moby/issues/2259 54 | USER root 55 | 56 | # Move Tizen studio from home because we mount home to host volume, and create symlink to keep everything working. 57 | RUN mv ${HOME}/tizen-studio /tizen-studio \ 58 | && ln -s /tizen-studio ${HOME}/tizen-studio 59 | 60 | # Copy and extract webOS CLI 61 | ARG WEBOS_CLI_VERSION=1.12.4-j27 62 | ENV LG_WEBOS_TV_SDK_HOME=/webOS_TV_SDK 63 | ENV WEBOS_CLI_TV=${LG_WEBOS_TV_SDK_HOME}/CLI/bin 64 | COPY vendor/webOS_TV_CLI_linux_${WEBOS_CLI_VERSION}.tgz ./webos_cli.tgz 65 | RUN mkdir -p ${LG_WEBOS_TV_SDK_HOME} 66 | RUN tar -xvzf webos_cli.tgz -C ${LG_WEBOS_TV_SDK_HOME} \ 67 | && chmod -R +x ${WEBOS_CLI_TV} \ 68 | && rm webos_cli.tgz 69 | 70 | # Add tizen/webos cli to PATH 71 | ENV PATH $PATH:/tizen-studio/tools/:/tizen-studio/tools/ide/bin/:/tizen-studio/package-manager/:${WEBOS_CLI_TV} 72 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # docker-tizen-webos-sdk 2 | Docker image with [Samsung Tizen CLI](https://developer.samsung.com/smarttv/develop/getting-started/using-sdk/command-line-interface.html) 3 | and [LG webOS CLI](http://webostv.developer.lge.com/sdk/tools/using-webos-tv-cli/). 4 | Allows to develop, build, launch and debug Smart TV apps without installing Tizen Studio and webOS SDK. 5 | Available CLI commands: 6 | * `tizen` 7 | * `sdb` 8 | * `ares-*` 9 | 10 | ## Contents 11 | 12 | 13 | 14 | 15 | - [Requirements](#requirements) 16 | - [Usage](#usage) 17 | - [Samsung Tizen TV CLI](#samsung-tizen-tv-cli) 18 | - [Get info about TV](#get-info-about-tv) 19 | - [Connect to TV](#connect-to-tv) 20 | - [List connected TVs](#list-connected-tvs) 21 | - [Get TV capabilities](#get-tv-capabilities) 22 | - [Get list of installed apps](#get-list-of-installed-apps) 23 | - [Launch app on TV](#launch-app-on-tv) 24 | - [Pack app](#pack-app) 25 | - [Install app](#install-app) 26 | - [Debug app](#debug-app) 27 | - [Close app](#close-app) 28 | - [Uninstall app](#uninstall-app) 29 | - [Pack, install and launch app on TV in single command](#pack-install-and-launch-app-on-tv-in-single-command) 30 | - [LG WebOS TV CLI](#lg-webos-tv-cli) 31 | - [Changelog](#changelog) 32 | - [3.0](#30) 33 | - [2.0](#20) 34 | - [1.0](#10) 35 | - [Development](#development) 36 | - [Build container](#build-container) 37 | - [Slow way](#slow-way) 38 | - [Fast way](#fast-way) 39 | - [Update webOS sdk](#update-webos-sdk) 40 | - [Test](#test) 41 | - [Debug](#debug) 42 | - [Generate TOC](#generate-toc) 43 | - [Publish to Docker Hub](#publish-to-docker-hub) 44 | - [Remove unused images](#remove-unused-images) 45 | 46 | 47 | 48 | ## Requirements 49 | The only requirement is docker: 50 | * for Mac/Windows - [Docker Desktop](https://www.docker.com/products/docker-desktop) 51 | * for Linux - [Docker Engine](https://docs.docker.com/engine/install/) 52 | 53 | ## Usage 54 | Run `bash` session inside container: 55 | ``` 56 | docker run -it --rm -v tvdata:/home/developer vitalets/tizen-webos-sdk bash 57 | ``` 58 | > Named volume `tvdata` is important for saving your data between container runs. 59 | 60 | Now you have Ubuntu with `sdb`, `tizen`, and `ares-*` commands available: 61 | ``` 62 | ~# tizen version 63 | Tizen CLI 2.5.21 64 | 65 | ~# sdb version 66 | Smart Development Bridge version 4.2.12 67 | 68 | ~# ares-setup-device --version 69 | Version: 1.10.4-j1703-k 70 | ``` 71 | 72 | Container is intentionally started under the `root` user. Starting under non-root user may cause [permissions issue](https://github.com/moby/moby/issues/2259) when attaching volumes. If you have problems with runnig tizen `package-manager` try to run container under `developer` user (see [#6](https://github.com/vitalets/docker-tizen-webos-sdk/issues/6)): 73 | ```bash 74 | docker run --user developer -it --rm -v tvdata:/home/developer vitalets/tizen-webos-sdk bash 75 | ``` 76 | 77 | ## Samsung Tizen TV CLI 78 | ### Get info about TV 79 | If you have Samsung TV in the same network as your host machine, 80 | you can get TV info from inside the container: 81 | ``` 82 | curl http://TV_IP:8001/api/v2/ 83 | ``` 84 | > You may be asked on TV to allow external connections (once). 85 | 86 |
87 | Example Output 88 | 89 | { 90 | "device":{ 91 | "FrameTVSupport":"false", 92 | "GamePadSupport":"true", 93 | "ImeSyncedSupport":"true", 94 | "Language":"ru_RU", 95 | "OS":"Tizen", 96 | "PowerState":"on", 97 | "TokenAuthSupport":"true", 98 | "VoiceSupport":"false", 99 | "WallScreenRatio":"0", 100 | "WallService":"false", 101 | "countryCode":"RU", 102 | "description":"Samsung DTV RCR", 103 | "developerIP":"192.168.1.64", 104 | "developerMode":"1", 105 | "duid":"uuid:88d68ee4-cffc-47c4-894f-6d46ca51333a", 106 | "firmwareVersion":"Unknown", 107 | "id":"uuid:88d68ee4-cffc-47c4-894f-6d46ca51333a", 108 | "ip":"192.168.1.66", 109 | "model":"19_MUSEL_UHD", 110 | "modelName":"UE43RU7400UXRU", 111 | "name":"[TV] Samsung 7 Series (43)", 112 | "networkType":"wireless", 113 | "resolution":"3840x2160", 114 | "smartHubAgreement":"true", 115 | "ssid":"94:4a:0c:86:c7:00", 116 | "type":"Samsung SmartTV", 117 | "udn":"uuid:88d68ee4-cffc-47c4-894f-6d46ca51333a", 118 | "wifiMac":"B8:BC:5B:93:7E:D2" 119 | }, 120 | "id":"uuid:88d68ee4-cffc-47c4-894f-6d46ca51333a", 121 | "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", 122 | "name":"[TV] Samsung 7 Series (43)", 123 | "remote":"1.0", 124 | "type":"Samsung SmartTV", 125 | "uri":"http://192.168.1.66:8001/api/v2/", 126 | "version":"2.0.25" 127 | } 128 |
129 | 130 | ### Connect to TV 131 | Before running any `tizen` / `sdb` command you should connect to TV. 132 | Please ensure that TV is in [Developer Mode](https://developer.samsung.com/smarttv/develop/getting-started/using-sdk/tv-device.html) 133 | and Developer IP equals to your host IP (check `developerMode` and `developerIP` in curl response). 134 | ```bash 135 | $ sdb connect 192.168.1.66 136 | ``` 137 | Output: 138 | ``` 139 | * Server is not running. Start it now on port 26099 * 140 | * Server has started successfully * 141 | connecting to 192.168.1.66:26101 ... 142 | connected to 192.168.1.66:26101 143 | ``` 144 | 145 | ### List connected TVs 146 | ``` 147 | $ sdb devices 148 | ``` 149 | Output: 150 | ``` 151 | List of devices attached 152 | 192.168.1.66:26101 device UE43RU7400UXRU 153 | ``` 154 | 155 | ### Get TV capabilities 156 | ``` 157 | $ sdb -s 192.168.1.66 capability 158 | ``` 159 | Output: 160 | ``` 161 | secure_protocol:enabled 162 | intershell_support:disabled 163 | filesync_support:pushpull 164 | ... 165 | ``` 166 | 167 | ### Get list of installed apps 168 | ``` 169 | $ sdb -s 192.168.1.66 shell 0 applist 170 | ``` 171 | Output: 172 | ``` 173 | Application List for user 5001 174 | User's Application 175 | Name AppID 176 | ================================================= 177 | 'HdmiCec' 'org.tizen.hdmicec' 178 | 'automation-app' 'org.tizen.automation-app' 179 | ... 180 | ``` 181 | ### Launch app on TV 182 | ``` 183 | $ tizen run -s 192.168.1.66:26101 -p 9Ur5IzDKqV.TizenYouTube 184 | ``` 185 | Output: 186 | ``` 187 | Launching the Tizen application... 188 | -------------------- 189 | Platform log view 190 | -------------------- 191 | ... successfully launched pid = 1656 with debug 0 192 | Tizen application is successfully launched. 193 | ``` 194 | or 195 | ``` 196 | $ sdb -s 192.168.1.66:26101 shell 0 was_execute 9Ur5IzDKqV.TizenYouTube 197 | ``` 198 | 199 | ### Pack app 200 | Sample developer certificate is included, so you can pack your app without any setup (for development). 201 | Author.p12 / distributor.p12 password is `developer`. 202 | Run container with mounting app source `./src` into `/app`: 203 | ``` 204 | docker run -it --rm -v ./src:/app -v tvdata:/home/developer vitalets/tizen-webos-sdk bash 205 | ``` 206 | Create `wgt` package: 207 | ``` 208 | tizen package -t wgt -o /home/developer -- /app 209 | ``` 210 | Output: 211 | ``` 212 | The active profile is used for signing. If you want to sign with other profile, please use '--sign' option. 213 | Author certificate: /home/developer/author.p12 214 | Distributor certificate : /home/developer/tizen-studio/tools/certificate-generator/certificates/distributor/tizen-distributor-signer.p12 215 | Excludes File Pattern: {.manifest.tmp, .delta.lst} 216 | Ignore File: /app/.manifest.tmp 217 | Package File Location: /home/developer/MyTvApp.wgt 218 | ``` 219 | 220 | ### Install app 221 | ``` 222 | $ tizen install -s 192.168.1.66:26101 --name MyTvApp.wgt -- /home/developer 223 | ``` 224 | Output: 225 | ``` 226 | Transferring the package... 227 | Transferred the package: /home/developer/MyTvApp.wgt -> /home/owner/share/tmp/sdk_tools/tmp 228 | Installing the package... 229 | -------------------- 230 | Platform log view 231 | -------------------- 232 | install TESTABCDEF.MyTvApp 233 | package_path /home/owner/share/tmp/sdk_tools/tmp/MyTvApp.wgt 234 | was_install_app return WAS_TRUE 235 | app_id[TESTABCDEF.MyTvApp] install start 236 | ... 237 | app_id[TESTABCDEF.MyTvApp] install completed 238 | spend time for wascmd is [1898]ms 239 | cmd_ret:0 240 | Installed the package: Id(TESTABCDEF.MyTvApp) 241 | Tizen application is successfully installed. 242 | Total time: 00:00:02.895 243 | ``` 244 | > You may need to rename wgt before installing 245 | > because `tizen install` does not work properly with spaces and non-latin symbols in wgt filename 246 | 247 | ### Debug app 248 | Launch app in debug mode: 249 | ``` 250 | $ sdb -s 192.168.1.66:26101 shell 0 debug TESTABCDEF.MyTvApp 251 | ``` 252 | Output: 253 | ``` 254 | ... successfully launched pid = 12915 with debug 1 port: 34541 255 | ``` 256 | Then open in chrome url `http://{TV_IP}:{PORT}` using port from previous command. 257 | 258 | ### Close app 259 | ``` 260 | $ sdb -s 192.168.1.66:26101 shell 0 kill TESTABCDEF 261 | ``` 262 | Output: 263 | ``` 264 | Pkgid: TESTABCDEF is Terminated 265 | spend time for pkgcmd is [246]ms 266 | ``` 267 | > Note using only `packageId` instead of full `appId`. 268 | 269 | ### Uninstall app 270 | ``` 271 | $ tizen uninstall -s 192.168.1.66:26101 -p TESTABCDEF.MyTvApp 272 | ``` 273 | Output: 274 | ``` 275 | -------------------- 276 | Platform log view 277 | -------------------- 278 | uninstall TESTABCDEF.MyTvApp 279 | app_id[TESTABCDEF.MyTvApp] uninstall start 280 | ... 281 | app_id[TESTABCDEF.MyTvApp] uninstall completed 282 | spend time for wascmd is [2027]ms 283 | cmd_ret:0 284 | Total time: 00:00:02.703 285 | ``` 286 | 287 | ### Pack, install and launch app on TV in single command 288 | App sources are in `./src`. 289 | The following env variables are used: 290 | - `TV_IP=192.168.1.66` 291 | - `APP_ID=TESTABCDEF.MyTvApp` (from config.xml) 292 | - `APP_NAME="My TV App"` (from config.xml) 293 | ``` 294 | docker run -it --rm \ 295 | -e TV_IP=192.168.1.66 \ 296 | -e APP_ID=TESTABCDEF.MyTvApp \ 297 | -e APP_NAME="My TV App" \ 298 | -v tvdata:/home/developer 299 | -v ./src:/app \ 300 | vitalets/tizen-webos-sdk /bin/bash -c '\ 301 | tizen package -t wgt -o . -- /app \ 302 | && mv "$APP_NAME.wgt" app.wgt \ 303 | && sdb connect $TV_IP \ 304 | && tizen install -s $TV_IP:26101 --name app.wgt -- . \ 305 | && tizen run -s $TV_IP:26101 -p $APP_ID' 306 | ``` 307 | 308 | ## LG WebOS TV CLI 309 | tbd 310 | 311 | ## Changelog 312 | #### 3.0 313 | - update Tizen Studio to 5.5 314 | - update webOS sdk to 1.12.4-j27 315 | 316 | #### 2.0 317 | - update Tizen Studio to 4.1.1 318 | - update webOS sdk to 1.11.0 319 | 320 | #### 1.0 321 | Initial version 322 | 323 | ## Development 324 | 325 | ### Build container 326 | ##### Slow way 327 | ```bash 328 | docker build -t vitalets/tizen-webos-sdk . 329 | ``` 330 | ##### Fast way 331 | 1. Download Tizen Studio installer to `vendor` dir (change version if needed): 332 | ```bash 333 | TIZEN_STUDIO_VERSION=5.5 334 | wget http://download.tizen.org/sdk/Installer/tizen-studio_${TIZEN_STUDIO_VERSION}/web-cli_Tizen_Studio_${TIZEN_STUDIO_VERSION}_ubuntu-64.bin \ 335 | -O vendor/web-cli_Tizen_Studio_${TIZEN_STUDIO_VERSION}_ubuntu-64.bin 336 | ``` 337 | 338 | 2. Build container using downloaded Tizen Studio installer (change version if needed): 339 | ```bash 340 | TIZEN_STUDIO_VERSION=5.5 341 | docker run -d --rm --name nginx-temp -p 8080:80 -v $(pwd)/vendor:/usr/share/nginx/html:ro nginx \ 342 | && docker build -t vitalets/tizen-webos-sdk . \ 343 | --build-arg TIZEN_STUDIO_URL=http://172.17.0.1:8080/web-cli_Tizen_Studio_${TIZEN_STUDIO_VERSION}_ubuntu-64.bin \ 344 | ; docker stop nginx-temp 345 | ``` 346 | 347 | ### Update webOS sdk 348 | 1. Download [latest installer for linux](https://webostv.developer.lge.com/develop/tools/cli-installation) and move it to `vendor` folder 349 | 2. In `Dockerfile` change `WEBOS_CLI_VERSION` to corresponding version 350 | 3. Build docker image 351 | 352 | ### Test 353 | ```bash 354 | ./test.sh 355 | ``` 356 | 357 | ### Debug 358 | ``` 359 | docker run -it --rm --platform linux/amd64 -v /home/developer vitalets/tizen-webos-sdk bash 360 | ``` 361 | And check sdk commands, e.g.: 362 | ``` 363 | tizen version 364 | # or 365 | ares-setup-device --version 366 | ``` 367 | 368 | ### Generate TOC 369 | ``` 370 | docker run --rm -it -v $(pwd):/usr/src jorgeandrada/doctoc --github README.md 371 | ``` 372 | 373 | ### Publish to Docker Hub 374 | 1. Check [existing tags](https://hub.docker.com/repository/docker/vitalets/tizen-webos-sdk/tags?page=1&ordering=last_updated) on docker hub. 375 | 2. Set new tag and push to registry: 376 | ```bash 377 | TAG=x.x 378 | docker tag vitalets/tizen-webos-sdk:latest vitalets/tizen-webos-sdk:$TAG 379 | docker push vitalets/tizen-webos-sdk:$TAG 380 | ``` 381 | 382 | ### Remove unused images 383 | ```bash 384 | docker rmi $(docker images --filter "dangling=true" -q --no-trunc) 385 | ``` 386 | --------------------------------------------------------------------------------