OBSOLETE Android port. Now merged into mainline!
C C++ Shell Assembly Objective-C Pascal Other
Pull request Compare This branch is 255 commits ahead, 1706 commits behind android-rebase-11.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
XBMC-ATV2.xcodeproj
XBMC-IOS.xcodeproj
XBMC.xcodeproj
addons
build-aux
docs/manpages
doxygen_resources
language
lib
m4
media
project
sounds/Bursting Bubbles
system
tools
userdata
xbmc
.dummy.am
.gitignore
.gitmodules
CONTRIBUTORS
LICENSE.GPL
Makefile.in
Makefile.include.in
README.android
README.armel
README.ios
README.linux
README.osx
README.ubuntu
bootstrap
configure.in
copying.txt
gitrev.sh
keymapping.txt
xbmc-xrandr.c

README.android

TOC
1. Introduction
2. Installing and setting up the Android environment
3. Getting the source code
4. Installing the required Ubuntu packages
5. How to compile
6. Installing XBMC in an Android system
7. Running and debugging XBMC in an Android system
8. Architecture
9. Useful Commands

-----------------------------------------------------------------------------
1. Introduction
-----------------------------------------------------------------------------

We currently recommend Ubuntu Hardy (8.04) or later. The setup can also be
done with OSX or Windows (using Cygwin) but may require extra work not
described in this document.

NOTE TO NEW LINUX USERS: All lines that are prefixed with the '#'
character are commands that need to be typed into a terminal window /
console (similar to the command prompt for Windows). Note that the '#'
character itself should NOT be typed as part of the command.

-----------------------------------------------------------------------------
2. Installing and setting up the Android environment
-----------------------------------------------------------------------------

To develop XBMC for Android the Android SDK and NDK are required.
Because the Android NDK is lacking support for wide characters (wchar_t)
which XBMC relies on for Unicode implementation, a third-party NDK
from Crystax is being used.

--------------------------------------------------------------------
2.1. Getting the Android SDK and NDK
--------------------------------------------------------------------

To get the Android SDK, go to http://developer.android.com/sdk and
download the latest version for your operating system. The Crystax NDK
can be downloaded from http://www.crystax.net/en/android/ndk

[NOTICE] Compiling XBMC for Android requires at least Android NDK
         Revision 7b. Android NDK Revision 7 and earlier do not work
         properly for our cause. The corresponding Crystax NDK version
         is android-ndk-r7-crystax-5.
         
After downloading the SDK and NDK extract the files contained in the
archives to your harddisk.

Make sure you have a recent JRE and JDK installed otherwise the
Android SDK will not work.

--------------------------------------------------------------------
2.2. Installing Android SDK packages
--------------------------------------------------------------------

After having extracted the Android SDK to <android-sdk> you need to
install some android packages using the Android SDK Manager:

   # cd <android-sdk>/tools
   # android &

Install at least the following packages:
  - Tools
    - Android SDK Tools
    - Android SDK Platform-tools
  - Android 2.3.3 (API 10)
    - SDK Platform

--------------------------------------------------------------------
2.3. Creating an Android Virtual Device
--------------------------------------------------------------------

In the Android SDK Manager (see 2.2) go to Tools -> Manage AVDs...
to open the Android Virtual Device Manager. Click on "New..." to
create a new Android Virtual Device (AVD). Enter a name (<avd-name>)
and select "Android 2.3.3 - API Level 10" as the Target. For the
"SD Card Size" choose at least 512 MB. In the "Hardware" part specify
at least "256" MB for "Device ram size". Click on "Create AVD" to
create your AVD.

--------------------------------------------------------------------
2.4. Setup the Android toolchain
--------------------------------------------------------------------

To be able to compile XBMC and the libraries it depends on for the
Android platform you first need to setup an Android toolchain using
the Android NDK which you earlier extracted to <android-ndk>.

   # cd <android-ndk>
   # ls platforms
   # cd build/tools
   # ./make-standalone-toolchain.sh --ndk-dir=<android-ndk> \
     --platform=android-<x> --install-dir=<android-toolchain>/android-<x> \
     --toolchain=arm-linux-androideabi-4.4.3

The output of "ls platforms" gives you a list of available platforms
which you can pass to the --platform option of the
make-standalone-toolchain.sh script. Make sure that <x> is at least 9.
The --install-dir option (and therefore the <android-toolchain> value)
specifies the path whereto the script will copy the necessary files.

-----------------------------------------------------------------------------
3. Getting the source code
-----------------------------------------------------------------------------

   # sudo apt-get install git-core
   # cd $HOME
   # git clone git://github.com/xbmc/android.git xbmc-android
   # cd xbmc-android
   # git submodule update --init addons/skin.touched

-----------------------------------------------------------------------------
4. Installing the required Ubuntu packages
-----------------------------------------------------------------------------

   # sudo apt-get install git-core make g++ gcc cvs rpl TODO
   
If you run a 64bit operating system you will also need to get ia32-libs

  # sudo apt-get install ia32-libs

*** For developers and anyone else who compiles frequently it is recommended to use ccache
sudo apt-get install ccache

*** A tip for those with multiple computers at home is to check out distcc (totally unsupported from xbmc of course)
sudo apt-get install distcc

-----------------------------------------------------------------------------
5. How to compile
-----------------------------------------------------------------------------

Compiling XBMC for Android consists of compiling the libraries XBMC depends
on with the Android toolchain and creating an Android Application Package
(APK) which can be installed in an Android system.

--------------------------------------------------------------------
5.1. Building dependencies
--------------------------------------------------------------------

   # cd $HOME/xbmc-android/tools/android/depends

Open the script setup-sdk.sh in your preferred text editor and complete
the following variable definitions:
  
  - NDKROOT:        Path to the root directory of the Android NDK (<android-ndk>)
  - SDKROOT:        Path to the root directory of the Android SDK (<android-sdk>)
  - TARBALLS:       Path to a directory where the tarballs containing the 
                    sources of the dependencies are stored after downloading
  - TOOLCHAIN:      Path to the Android toolchain used for compiling the
                    dependencies (<android-toolchain>/android-<x>)
  - XBMCPREFIX:     Path to the directory where the built binaries and libraries
                    will be stored (e.g. $HOME/xbmc-android/tools/android/build)
  - HOST:           Name/Identification of the host architecture
                    e.g. arm-linux-androideabi or i686-android-linux
  - PLATFORM:       Name/Identification of the platform
                    e.g. armeabi (for ARMv5) or armeabi-v7a (for ARMv7-a)
  - PLATFORM_FLAGS: Platform-specific compiler flags
                    e.g. "-march=armv7-a -mtune=cortex-a9 -mfloat-abi=softfp -mfpu=neon -D__ARM_ARCH_7__ -D__ARM_ARCH_7A__ -DANDROID -Os"
                
   # ./setup-sdk.sh
   # make

--------------------------------------------------------------------
5.2. Building the APK
--------------------------------------------------------------------

   # cd $HOME/xbmc-android/tools/android/packaging
   # make

This will create the debug APK named "xbmcapp-debug.apk" in the
"images" sub-directory

-----------------------------------------------------------------------------
6. Installing XBMC in an Android system
-----------------------------------------------------------------------------

To install XBMC through the previously built APK in an Android system you can
either install it on a real device (smartphone/tablet/...) running Android
2.3.x or use the Android emulator and the previously created AVD.

--------------------------------------------------------------------
6.1. Installing XBMC in the Android emulator
--------------------------------------------------------------------

   # cd $HOME/xbmc-android/tools/android/packaging
   # emulator-arm -avd <avd-name> -wipe-data &
   # adb install images/xbmcapp-debug.apk

--------------------------------------------------------------------
6.2. Installing XBMC on the Android device
--------------------------------------------------------------------

Make sure your Android device is connected to your computer through
USB. Furthermore you have to enable the following option in your
device's Android settings:

  - Applications
    [X] Unknown sources

   # cd $HOME/xbmc-android/tools/android/packaging
   # adb devices
   # adb -s <device-id> install images/xbmcapp-debug.apk
      
The <device-id> can be retrieved from the list returned by the
"adb devices" command and is the first value in the row representing
your device.

-----------------------------------------------------------------------------
7. Running and debugging XBMC in an Android system
-----------------------------------------------------------------------------

After installing XBMC's APK in an Android system you can start it using its
Launcher icon in Android's Application Launcher.

--------------------------------------------------------------------
7.1. Debugging XBMC
--------------------------------------------------------------------

To be able to see what is happening while running XBMC you first need
to enable USB debugging in your Android settings (this is already done
when using the emulator):

  - Applications
    [X] Unknown sources
     -  Development
      [X] USB debugging

To access the log output of your Android system run (the -s parameter
and the <device-id> may not be needed when using the Android emulator)

  # adb -s <device-id> logcat


--------------------------------------------------------------------
7.2. GDB
--------------------------------------------------------------------

GDB can be used to debug, though the support is rather primitive. Rather than
using gdb directly, you will need to use ndk-gdb which wraps it. Do NOT trust
the -p/--project switches, as of ndk7b they do not work. Instead you will need
to cd to tools/android/packaging/xbmc and execute it from there.

  # ndk-gdb --start

This will open the installed version of XBMC and break. The warnings can be
ignored as we have setup the appropriate paths already.

Caveats:

- Anything related to dlopen'd libs is hit or miss. Not good when libxbmc.so is
  run that way. Basic functionality works, though be aware that breakpoints may
  not be reliable yet.

- Timings during the first second or two can be strange because gdb doesn't
  know when we're actually into xbmc. For example, a breakpoint set for
  android_init will likely never be hit. Use of ndk-gdb's --delay switch may
  help.


--------------------------------------------------------------------
8. Architecture
--------------------------------------------------------------------

!!Warning!!
This is an early port with an emphasis on getting up and running. There are
several ugly hacks and a few methods that are flat-out disgusting. These need
to be cleaned up over time as we actually start running on devices.

The life of xbmcapp:
Android can not run native applications (in any supported fashion anyway), but
does allow for a purely c/c++ library to be loaded as a "native activity". This
This library has an android_main() entry point. Thus, we split xbmc into
libxbmc.so and a small main stub that calls it so that it can be run as an
application or a lib.

However, due to the flimsy nature of the android lib loader, we cannot just
stick android_main() directly into this lib and let it call in. The loader does
not load deps recursively, so it simply throws an error when trying to load the
native activity. Instead, we create a stub library that dlopens all of our deps
in reverse order, then finally libxbmc.so itself. From there we can call the
entry function and we're up and running as usual. There are probably many ways
to do this much cleaner, but this was the first that worked. This MUST be
re-evaluated.

So execution looks like this
Android calls into libxbmcapp.so directly which contains android_main(). It
loads our deps, loads libxbmc.so, calls XBMC_Init(), and we're into xbmc.

See here for a thorough explanation:
http://groups.google.com/group/android-ndk/browse_thread/thread/976136aa1d7b43a2

Additionally, Android does not use versioned solibs. libfoo.so.1 which is
typical on linux would not be found by the loader. This means that we must
strip the SONAME and NEEDED values out of the libs as well as changing the
filenames themselves. The cleaner solution would be to patch libtool/cmake/etc
to not add versioning in the first place. For now, we use the brute-force
approach of modifying the binary and blanking out the versions.
See the gory details in tools/android/packaging/fixsolib.sh.

See here for more info:
http://www.bernawebdesign.ch/byteblog/2011/11/23/creating-non-versioned-shared-libraries-for-android/

Development:
Typical android native activities are built with ndk-build which is a wrapper
around Make. It would be a nightmare to port our entire buildsystem over, so
instead we build as usual then package ourselves. It may be beneficial to use
ndk-build to do the actual packaging, but for now its behavior is emulated.

ABI:
Presently we are targeting armv5te as the android emulator is known to be
unstable with newer ABIs. This meant removing some of our asm (MathUtils and
Atomics). This is a temporary hack until we are able to run cleanly on native
hardware, at which point we should switch back to armv7a+neon as our minimum
supported hardware. Note that zero effort was made to disable these functions
gracefully. If it is desired to run XBMC fully in the emulator, these functions
will need to be fixed up to work properly.


--------------------------------------------------------------------
9. Useful Commands
--------------------------------------------------------------------

Below are a few helpful commands when building/debugging. These assume that pwd
is 'tools/android/packaging' and that the proper sdk/ndk paths are set.

-Install a new build over the existing one
  # adb -e install -r images/xbmcapp-debug.apk

-Launch XBMC on the emulator without the GUI
  # adb shell am start -a android.intent.action.MAIN -n org.xbmc/android.app.NativeActivity

-Kill a misbehaving XBMC
  # adb shell ps | grep org.xbmc | awk '{print $2}' | xargs adb shell kill

-Filter logcat messages by a specific tag (e.g. "XBMC")
  # adb logcat -s XBMC:V
  
-Create a (new) debug key to sign debug APKs
  # keytool -genkey -v -store -alias androiddebugkey -dname "CN=Android Debug,O=Android,C=US" -keypass android -storepass android -keyalg RSA -keysize 2048 -validity 10000
  
-Enable CheckJNI (BEFORE starting the application)
  # adb shell setprop debug.checkjni 1