Building a Tizen TV Application with Docker

Building a Tizen TV Application with Docker

I recently had a need to take a Tizen-ready application from GitHub and install it onto my compatible Samsung TV. However, I ran into endless issues running Tizen Studio from my virtual machine running Ubuntu 20.04 (on Hyper-V). It wasn't until I stumbled across some helpful suggestions which encouraged using a docker container to perform the build.

This blog post should help get you familiar with the steps I took from Ubuntu 20.04 to get a package built, packaged, and installed to my television.

Links you'll need:

Project Assumptions

Assume in Ubuntu I have my project I want Tizen to package up in ~/my-app/project , and that my current username is mitch.

Install Tizen Studio

So I found to create the authoring and distribution certificates, it'll be easiest to do so with the graphical interface (plus I couldn't find CLI documentation on distribution certificate creation).

Download and install Tizen Studio with IDE on your desktop OS or VM.

Install Certificate Manager and Samsung Certificate Extension using the Package Manager.

Register Samsung Account

Ensure you have a Samsung developer account - needed to generate authoring and distribution certificates. Sign up here.

Device ID

If you're going through these steps to deploy a Tizen app to your Samsung TV, please look up your device ID (DUID) before getting started. I found mine on TV going to:

  • Settings > Support > About this TV > (scroll down) "Unique Device ID"
    • Similar to MTCN1EIMGOPP4

Enabling Developer Mode on TV

In order to deploy your packaged application, you'll need to turn on Developer mode for your TV. Instructions on Samsung's site. You'll need your computer's IP address - and eventually - your TV's IP address. Collect those items now, too.

Create Profile and Certificates

  1. Create a new profile.
  2. Select "Samsung" type.
  3. I chose "TV" since that's the application type I wanted to package.
  4. Name your profile. I chose "dev".
  5. Create a new Authoring certificate.
    • Enter your name and a unique password. Save this somewhere handy, we'll need it later.
    • Keep the box checked to use same password - I am not using anything permanent here.
  6. You'll now need to sign into your Samsung account. It'll open up an embedded window to sign in.
  7. ⚠ Note the location of the created certificate. We'll need this path later. For me, this was /home/mitch/SamsungCertificate/dev.
  8. Click next and create new Distributor certificate.
  9. Keep as "Public" and the password should be identical and pre-filled to your Authoring certificate password.
  10. Enter your device ID (DUID) below (if deploying to physical TV, not emulator).
  11. You'll now have a distributor certificate dropped in same path as your authoring certificate, and your profile is now marked as "default"/"active".

Now that your certificates exist, let's copy them out of that folder to where our application is.

cp -R ~/SamsungCertificate/dev ~/my-app
ls -al ~/my-app/dev
copy certificates to a path we're going to bind to our docker container

Tizen4Docker Configuration

Clone the Tizen4Docker repository.

# mkdir ~/src
# cd ~/src
git clone https://github.com/kamildzi/tizen4docker
cd tizen4docker
# create our environment variables file
touch .env

See the .env.example file. Copy contents into our new file called .env. This is where we'll add our specific details. The README file should help you through each configuration area.

When you get to volumes, here's where we want to make sure our project and certificates folders are accessible from the docker container itself. Since tizen CLI commands will need to access them to build and package our application.

First, create folders that will house our Docker container's Tizen Studio installation files. We will use the -data folder path later to configure certificate profile.

mkdir -p ~/tizen-docker/tizen-studio
mkdir -p ~/tizen-docker/tizen-studio-data

Now, compare the .env.example to the .env file here to see the changes I made.

LOCAL_WORKSPACE=/home/someuser/Documents/Tizen/docker-workspace
LOCAL_TIZEN_STUDIO_DIRECTORY=/home/someuser/Documents/Tizen/docker-volumes/tizen-studio
LOCAL_TIZEN_STUDIO_DATA_DIRECTORY=/home/someuser/Documents/Tizen/docker-volumes/tizen-studio-data
.env.example
LOCAL_WORKSPACE=/home/mitch/my-app
LOCAL_TIZEN_STUDIO_DIRECTORY=/home/mitch/tizen-docker/tizen-studio
LOCAL_TIZEN_STUDIO_DATA_DIRECTORY=/home/mitch/tizen-docker/tizen-studio-data
.env

In this configuration, when Docker container starts, /home/mitch/workspace will be in the container equivalent to my local directory /home/mitch/my-app.

VM Notes

Since I'm running Ubuntu 20.04 in a VM within my host OS, I had to find the proper XSOCK value beyond the default display of 0.

ls /tmp/.X11-unix/
# X0   X10

# I needed to use X10 in .env settings

# ...
# XSOCK=/tmp/.X11-unix/X10
# DISPLAY=:10

Running Tizen4Docker

Once your .env file is ready to go, let the container do its thing.

cd ~/src/tizen4docker
chmod +x runTizen.sh
./runTizen.sh

If all is good, you'll get Eclipse asking you where you want your workspace. Choose the default, Tizen Studio will launch, and you'll see your project folder in there.

You can use the Package Manager in Tizen Studio to install any targets/tools you need.

You'll want to fire up Certificate Manager in Tizen Studio at this time and create a new profile. We already did this once (on host OS) but now it needs to be done from within the docker container. However, this time, we're going to import our existing certificates.

  • Tools > Certificate Manager
  1. Create new Profile (provide a name)
  2. Select existing authoring certificate. Path for me was /home/mitch/workspace/dev.
  3. Provide password.
  4. Repeat for distributor certificate.
  5. Your newly created profile should now be active!

Connecting to Shell with Tizen CLI in Container

To start running some CLI actions, we first need to get a shell going inside the Tizen4Docker container that's running. To do this, you'll first want to inspect your currently running Docker containers.

docker ps --format 'table {{.ID}}\t{{.Names}}\t{{.Image}}'

# should see at least an entry for tizen4docker
CONTAINER ID        NAMES                                 IMAGE
1640e20fa2c0        tizen4docker_tizen_run_845f100f53b6   tizen4docker_tizen

To enter into a bash shell, simply run the following:

# you can shorthand 164 from 1640e20fa2c0 above
docker exec -it 164 bash

mitch@1640e20fa2c0:/$

Building

# build tizen web app

cd ~/my-app/project

~/tizen-studio/tools/ide/bin/tizen build-web
In the Tizen4Docker shell
Note: use exclusion flags to trim down size if possible with your app. Docs

This should generate a directory named .buildResult that we'll use to package.

Packaging

cd ~/my-app/project

# package tizen app signed with authoring and distribution certificate
~/tizen-studio/tools/ide/bin/tizen package -t wgt -o . -- .buildResult

The active profile is used for signing. If you want to sign with other profile, please use '--sign' option.
An error has occurred. See the log file tizen-sdk/tools/ide/cli.log.
In the Tizen4Docker shell

That error log is found in ~/tizen-studio-data/cli/logs/cli.log. Contents indicated:

[ERROR] AbstractCLI.java(93) - org.tizen.common.sign.exception.CertificationException: Invaild password

Uh oh. You will encounter a keyring issue with docker container and reading password for certificate. The solution is to manually provide password in ~/tizen-studio-data/profiles/profiles.xml thanks to helpful forum post.

You can easily do this outside of the Docker container in the Tizen Studio Data directory we created. Use your text editor to navigate/edit file ~/tizen-docker/tizen-studio-data/profile/profiles.xml (this path is on your linux machine, not in the Docker context).

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles active="dev" version="3.1">
<profile name="dev">
<profileitem ca="/home/mitch/tizen-studio/tools/certificate-generator/certificates/developer/tizen-developer-ca.cer" distributor="0" key="/home/mitch/workspace/dev/author.p12" password="/home/mitch/workspace/dev/author.pwd" rootca=""/>
<profileitem ca="" distributor="1" key="/home/mitch/workspace/dev/distributor.p12" password="/home/mitch/workspace/dev/distributor.pwd" rootca=""/>
<profileitem ca="" distributor="2" key="" password="" rootca=""/>
</profile>
</profiles>

The two entries (/path/to/author.pwd and /path/to/distributor.pwd) must have their values changed from the filepath to the password itself. For example:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<profiles active="dev" version="3.1">
<profile name="dev">
<profileitem ca="/home/mitch/tizen-studio/tools/certificate-generator/certificates/developer/tizen-developer-ca.cer" distributor="0" key="/home/mitch/workspace/dev/author.p12" password="MyPassword1234" rootca=""/>
<profileitem ca="" distributor="1" key="/home/mitch/workspace/dev/distributor.p12" password="MyPassword1234" rootca=""/>
<profileitem ca="" distributor="2" key="" password="" rootca=""/>
</profile>
</profiles>

Now, try your build again!

cd ~/my-app/project
~/tizen-studio/tools/ide/bin/tizen package -t wgt -o . -- .buildResult

The active profile is used for signing. If you want to sign with other profile, please use '--sign' option.
Author certficate: /home/mitch/workspace/dev/author.p12
Distributor1 certificate : /home/mitch/workspace/dev/distributor.p12
Excludes File Pattern: {.manifest.tmp, .delta.lst}
Ignore File: /home/mitch/workspace/project/.buildResult/.manifest.tmp
Package File Location: /home/mitch/workspace/project/my-app.wgt
In the Tizen4Docker shell

Installing to your TV

To take the packaged up application and deploy it to your television...

# show devices (there won't be any to start with)
~/tizen-studio/tools/sdb devices

# connect using your TV's IP address (assume 192.168.1.123)
~/tizen-studio/tools/sdb connect 192.168.1.123

# successful message expected. check TV name for installation step
~/tizen-studio/tools/sdb devices

# install it!
~/tizen-studio/tools/ide/bin/tizen install -n my-app.wgt -t TVNAME
In the Tizen4Docker shell
Show Comments