Building an Android TV box on a C2

Moderators: mdrjr, odroid

Building an Android TV box on a C2

Unread postby goldpizza44 » Fri Dec 01, 2017 5:25 am

I have been using a C2 with LibreELEC for quite a while but was frustrated by the lack of Amazon Prime Video and Netflix. I was also using a wireless keyboard/mouse to control it which led to some spouse disapproval, so I wanted a proper TV remote control to control both the TV (power/volume) and the C2.

Here is a step by step of what I did. It assumes you are somewhat comfortable with Android (ie can find Apps, and Settings) and will require a bit of Linux via the Android Terminal Emulator. Hope it helps somebody else to reproduce.

My solution to get not only Kodi, but also Youtube TV, Amazon Prime Video and Netflix and a some individual Channel APPs was to install Android Marshmallow, and then install the Apps from the Google Playstore. Youtube TV, Amazon Prime Video and Kodi went right in. Netflix would not install from the Playstore but you can download the APK and load that. The Remote Control configuration took the most time, because I couldn't find a single WWW tutorial page that detailed the entire process. Hopefully this post will help others with that.

First step is to install Android on a Flash Card. Android for C2 can be downloaded from:

https://wiki.odroid.com/odroid-c2/os_images/android/android

At the time of this writing v3.5 is the latest version and that is what I used. Download the image, uncompress it (xz compressed) and install to the flash card using etcher (any), win32diskimager(windows) or dd(linux). https://wiki.odroid.com/troubleshooting/odroid_flashing_tools

Move the flash card into the Odroid-C2 plugged into a TV via HDMI along with a USB keyboard/mouse and power on. It takes a few minutes but eventually you should end up with a shiny new Android box and the mouse should allow you to navigate.

First order of business after Android is up may be to adjust the overscan on the screen. I found on my TV that all the edges were missing; couldn't see the notification bar at the top and the soft keys at the bottom were mostly chopped off. This is easily fixed by opening the "ODROID Utility" app. From this utility you can set resolution (default "autodetect" which works for me), use the arrows to adjust overscan, and turn off the blue LED which blinks to distraction. After adjusting the settings in this app, you must click "Apply and Reboot" which will reboot the Odroid.

Second order of business is to install Google Apps to get the Google Play store. Using the stock Android browser, the Google Apps APK is downloaded from:

http://opengapps.org/

On this page I chose:

  • Platform: ARM
  • Android: 6.0
  • Variant: pico

Pico is the minimum collection. You can try to install nano, micro etc...I am not interested in Calendar or other apps on my TV box, but I believe they will work.

Clicking Download will pull a ZIP file into the Download folder. This ZIP file needs to be treated as an Android Update, and hence is loaded using the same Odroid Utility App used to update the Overscan and Blue LED above. Open the Odroid Utility app, and click on the upper right corner (three dots). The menu present will have an option "Package install from storage" which is clicked. On the next page Choose "File Manager" and navigate to the Download folder where you will select the open_gapps ZIP file. This will ask to proceed at which time the odroid will reboot and the Google Apps installed.


After Install is complete you can open the Google Play Store app and install the following:
  • Amazon Prime Video
  • Kodi
  • Chrome Browser
  • Pluto TV
  • VPN client (if desired...I use OpenVPN)

There are a lot of video Apps...not all of them are TV friendly...install and try as desired.

By default this Android setting:
settings -> security -> untrusted sources

is set to YES. This is needed to install Netflix. Netflix was the one bad boy who would is not available on Google Play Store. Apparently Netflix does not deem Odroid C2 to be worthy of its app and has instructed the Playstore to not make it available.

However, Netflix has a help page with a link to their v4.16 version of the APK:

https://help.netflix.com/en/node/57688

I downloaded that APK and installed with FileManager. It runs well with the remote control. There are newer versions of the Netflix APKs available from:

https://www.apkmirror.com/apk/netflix-inc/netflix/

but when I downloaded a couple of these I found they were NOT remote control friendly...not sure why, so I went back to the v4.16 which does everything I need.

Configuring the apps is the same as on any other platform. My Kodi talks to a MythTV backend on another server which does all the LiveTV recording and manages my Movie collection. Finding the MythTV PVR addon was a bit of a challenge in Krypton. It is already in Addons->My Addons, but in disabled state...that's an hour of my life I won't get back...

REMOTE CONTROL

Speaking of time I won't get back, here is about 8 hours of fun condensed for Remote Control. Other members of the family don't get this whole Keyboard/Mouse thing on a TV. According to them, Keyboards and Mice are for Computers, TVs use Remote Controls. I have one of those Logitech Media Mouse/Keyboard things, but needless to say this is a losing battle in my house.

I am using the Odroid-C2 TV box with some old TVs that I inherited, and the original remotes were lost long ago. But I have laying around some old Dish Network 3.0 IR PVR remote controls which can be had on Ebay for under $10. In my opinion these are good sturdy remotes with good tactile feel and enough buttons that I should be able to do what I need. They are also "programmable" in that they come with a list of TV and other Device Codes which cause them to emulate the other manufacturer's remotes.

It was pretty easy to find the code to control my old TV. Power, Volume Up, Volume Down and Mute are all I really need. I thought I wanted "Input select" to work so I can change HDMI ports but nothing I did could get that remote button to work...fortunately the Odroid is the only input I have so no switching needed. If I ever add a second HDMI device it will probably require a trip from the armchair to the TV to switch devices using the buttons on the TV; or find a different Remote control and do this whole programming thing again.

The first source of frustration was finding a Device code that would activate all the buttons with the right protocol. Odroid-C2 uses the Amlogic S905 chip which contains an interface to the Infrared receiver. The Hardkernel Android OS install contains the 'amremote' driver built into the kernel (ie not loaded as a module). As far as I can tell the 'amremote' driver only recognizes the NEC Infrared Protocol. IR codes in other protocols (R5/R6 or Sony) simply are ignored by the amremote driver. If you want to read more on Consumer IR, check out https://en.wikipedia.org/wiki/Consumer_IR.

Armed with a list of a couple hundred codes, I sought out a remote control device code that would send NEC codes for all the buttons. Frustration set in when I found that many Devices in the Dish Network remote control would only send codes for a limited set of buttons....I had a really hard time finding one that would send codes on the 5 navigation buttons (up, down, left, right, center). Many codes would do only 3 (up/down/center or left/right/center), or 4 buttons, but not all 5. I finally found a Memorex DVD player (code 709) which did all 5 navigation directions plus all the number buttons on the remote. It would NOT send the '*' or the '#' nor volume/mute. Volume/Mute are relegated to the TV code and so I can only control the TV volume using the buttons, not the Android Volume.

But the "number keys" are largely useless for a TV box (I never use channel numbers any more), so in the remote.conf below I repurpose the number keys to do things like Android HOME, Android Volume UP/Down/Mute, Fast Forward/Reverse, etc. Certain family members will need to get used to that.

To understand how an incoming IR signal gets to the App correctly you need to realize that there are 3 separate signals involved:
  • The IR code as sent by the Remote
  • The Linux KEYCODE
  • The Android ACTION code

The trick is to map the incoming IR code to the correct Andoid ACTION code via some Linux KEYCODE, and this conversion is done by two separate files in Android:
  • /system/etc/remote.conf -- maps IR code to Linux Key Code
  • /system/usr/keylayout/Vendor_0001_Product_0001.kl -- maps Linux Key Code to Android ACTION

In my case, both of these files needed manipulation, although I tried to limit the changes to the keylayout. To change these files I used the Android Terminal Emulator app which gets me a 'bash' shell, and the 'vi' editor. If you don't know the 'vi' editor, you may be able to copy the files to /storage, use the FileManager App that is installed and edit using that, and then copy back to the /system location. Below I rely on 'vi' and various Linux commands to get the job done.

First task is to change /system filesystem from ReadOnly to ReadWrite so that we can update the files. Open the Android Terminal Emulator app and type:
Code: Select all
su -
mount -o remount,rw /system


The first command (su -) gives you superUser privileges. The first time you use it you will get a popup asking whether this app (Android Terminal Emulator) should always get this privilege. I answered yes and made it permanent. It is assumed that all following commands will be done in with superUser privileges. If you leave Android Terminal Emulator and come back you may need to do 'su -' again.

The second command will change the /system filesystem from ReadOnly to ReadWrite.

Next we need to edit /system/etc/remote.conf to turn on Debugging. Debugging will allow us to determine what codes we are receiving. Change "debug_enable" from a '0' to '1' with vi and activate with remotecfg:
Code: Select all
vi /system/etc/remote.conf
remotecfg /system/etc/remote.conf


remote.conf is read by remotecfg which will parse the contents and then send the information to the amremote software in the Linux kernel. This is normally done once on boot as specified in /system/init.odroidc2.rc. It is convienient because we can make changes and then immediately activate them.

With debug_enable set to one, any remote sending an NEC protocol will be detected and the amremote software will log "errors" to the system log. We will use 'dmesg' to see that system log. Test the change now by using these commands:
Code: Select all
dmesg -c > /dev/null # clear previouly logged stuff we don't care about
while sleep 1;do dmesg;dmesg -c > /dev/null;done


With the "while sleep" running pressing a button on the remote control should elicit something like this:
[98086.788285@0] remote: Wrong custom code is 0x7c83ff00

The last four digits of the number at the end of the log message tells us what what remote type this is (0xff00 in my case). The default remote.conf from Odroid Android looks for code 0x4db2. I am not sure what the odds are that you have a remote with that code if you are not using the Remote available from HardKernel https://wiki.odroid.com/accessory/connectivity/ir_remote_controller). If you are unlucky and the remote you are using does transmit 0x4db2 then you will see something else in dmesg. If you see nothing in dmesg, then you are not using a remote that transmits NEC protocol and must find another remote (or device code).

In my case this is where I started searching the Dish Network 3.0 IR device codes looking for a suitable device. I set the device code in the remote, and hit the buttons to see if I got responses in dmesg. I tried many many codes until I was close enough to my requirements with the Memorex DVD code 709, which transmits remote type 0xff00.

The long HEX number 0x7c83ff00 is actually 2 pieces of real info. Break it up in into bytes:
7c 83 ff00

and you should notice that the first 2 bytes are ones complement of each other (ie 01111100 -> 10000011 -- zeros and ones flipped). Similarly, the 3rd/4th bytes are ones complement in many (but not all) cases. The "real" information is in bytes 2 and 3/4 (0x83 is the button, 0xff00 is the type of remote).

It is now time to set the type of remote you are using in remote.conf by setting the entry for "factory_code" and replacing the XXXX with the 4 digit code found above (I set mine to 0xff000001):
Code: Select all
vi remote.conf    # change factory_code = 0xXXXX0001
remotecfg /system/etc/remote.conf
while sleep 1;do dmesg;dmesg -c > /dev/null;done


After these commands you should again be able to press buttons and one of two things will happen:
  • You will see an error indicating the remote button doesn't map to anything
  • You will see information on what the button mapped to

[101131.973324@0] remote: scancode is 0x00c5,invalid key is 0x0000.
or
[101214.803355@0] remote: press ircode = 0xc5
[101214.903456@0] remote: scancode = 0x74,maptable = 0,code:0x3ac5ff00
[101214.903492@0]
[101214.993555@0] remote: release ircode 0xc5
[101214.997312@0] remote: scancode = 0x74,maptable = 0,code:0x00000000


The first one occurs because the button 0xc5 is not in remote.cfg. The second one occurs when the button is found in remote.cfg. If the remote you are using sends codes similar to those of the Hardkernel remote you may see the second type of message.

Finally the fun begins. You need to press every button and see what code it sends, and note that. Then you need to figure out what you want it to do and find the Android action in the Vendor_0001_Product_0001.kl file that corresponds to the action you want the button to do. Finally you need to get the Linux KEY code from Vendor_0001_Product_0001.kl that will be used to tie everything together.

These are the ANDROID actions I am using:
  • POWER -- key 116
  • HOME -- key 102
  • BACK -- key 15
  • MENU -- key 139
  • DPAD_CENTER -- key 97
  • DPAD_LEFT 1 -- key 105
  • DPAD_RIGHT -- key 106
  • DPAD_UP -- key 103
  • DPAD_DOWN -- key 108
  • VOLUME_UP -- key 115
  • VOLUME_DOWN -- key 114
  • VOLUME_MUTE -- key 113
  • MEDIA_REWIND -- key 121
  • MEDIA_FAST_FORWARD -- key 120
  • APP_SWITCH -- NO KEY available!

The last one "APP_SWITCH" is not in Vendor_0001_Product_0001.kl! Took me 2 hours to figure that one out. So I appropriated a key (158 -- formerly BACK) by updating Vendor_0001_Product_0001.kl with vi and changing "BACK" to "APP_SWITCH" on the appropriate line.

Now glue everything together by updating remote.conf in the key_begin/key_end section and possibly in the repeat_key_begin/repeat_key_end section. I don't rely on key repeats, so my repeat_key_begin/repeat_key_end section is empty. Also I am not relying on the mouse_begin/mouse_end section either.

My resulting remote.conf file looks like:

Code: Select all
work_mode = 0
repeat_enable = 1
repeat_delay = 40
repeat_period = 39
release_delay = 121
debug_enable = 0

factory_code = 0xff000001
left_key_scancode = 0x88
right_key_scancode = 0xc8
up_key_scancode = 0xc9
down_key_scancode = 0xd7
ok_key_scancode = 0x8b

mouse_begin
mouse_end

key_begin
0xc5 116 # Power
0x8b 97 # Center
0xc9 103 # Up
0xd7 108 # down
0x88 105 # Left
0xc8 106 # Right
0x93 15  # cancel
0x93 15  # Info
0x81 114   # 1 -- becomes VOLUME DOWN
0x83 113   # 2 -- becomes MUTE
0xc1 115   # 3 -- becomes VOLUME UP
0x82 121   # 4 -- becomes REWIND
0x80 139   # 5 -- becomes MENU
0xc0 120   # 6 -- becomes FF
0x8d 8     # 7
0x8f 158   # 8 -- APP SWITCH
0xcd 10  # 9
0x8c 102  # 0 -- becomes HOME
key_end

repeat_key_begin
repeat_key_end


Note that I also turned "debug_enable" off again by setting it to zero. After updating remote.conf again execute:

Code: Select all
remotecfg /system/etc/remote.conf


Now time to test the remote. You want to test each app as they can react differently to a particular code or ignore it completely. I am still not sure I have all the keys where I want them, but the system is functional and usable.

Make a backup of Vendor_0001_Product_0001.kl and remote.conf by copying them to /storage/emulated/0/Download and make sure they are saved in the /system filesystem. If you upgrade Android, you may find that these files need restoration or your remote won't work anymore.

Hope this is useful to at least one person. I will probably need to dig it up in the future so I can remember what I did.
goldpizza44
 
Posts: 1
Joined: Mon Nov 27, 2017 2:53 am
languages_spoken: english

Re: Building an Android TV box on a C2

Unread postby bhavesh.gangani » Thu Jul 05, 2018 9:39 am

Hello Sir,

Thank you so much for the details guide. It helped me a lot. None of the solutions on the forum worked but this!
The controls on Kodi work fine but None of them are working with android youtube app.

Does anyone have any idea how to get it working with youtube app (pause, play, rewind, fast forward etc.)?

Thank you.
bhavesh.gangani
 
Posts: 1
Joined: Thu Jul 05, 2018 9:34 am
languages_spoken: english
ODROIDs: C2


Return to Android

Who is online

Users browsing this forum: No registered users and 1 guest