Marko Gargenta_Remixing android
-
Author
droidcon-berlin -
Category
Technology
-
view
1.051 -
download
1
Embed Size (px)
Transcript of Marko Gargenta_Remixing android

Remixing AndroidMarko Gargenta @Marakana

About Marko Gargenta
1.1. Entrepreneur, Author, Speaker
Developer of Android Bootcamp for Marakana.
Instructor for 1,000s of developers on Android at Qualcomm, Cisco, Motorola, Intel,DoD and other great orgs.
Author of Learning Android published by O’Reilly.
Speaker at OSCON (3x), ACM, IEEE, SDC, AnDevCon. Co-Founder of SFAndroid.org
Co-Chair of Android Open conference: Android Open

Why Remix Android??
2.1. Vanilla is just not for everyone.
Because Android is open
Because custom is better
Because we can
re·mix/rēmiks/:
Verb:
Mix (something) again.
Noun:
A different version of an open operating system produced in such a way.

Remix What?!?
3.1. Cosmetics aside, we’re focusing on major surgery to Android OS.
Registering New Device: Marakana Alpha
Makefile Plumbing
Building Alpha Device
Adding Custom Kernel
Adding Native Libs
Adding Native Daemon
Exposing Libs via JNI
Registering New System Service
Extending Android Framework
Adding New App
Creating SDK Add-on

Android Stack: The High Level Overview

Android Stack: From Source to Device

Android Stack: Layer Interaction

Interaction Between Apps

Marakana Alpha

Getting the AOSP SourceInitialize the build environment
Download the source
Build the source
Run on device

Setting up the Directory Structure
Self-contained directory structure:
device/marakana/: Main placeholder for Marakana Alpha codebase.
device/marakana/alpha: Code that goes onto the device.
device/marakana/alpha-sdk_addon: Code that goes into the SDK add-on.
device/marakana/alpha-common: Shared codebase for device and SDK add-on.

Registering Marakana Alpha
11.1. To future-proof your changes, don’t sprinkle other people’s code - keep itseparate.
Create vendorsetup.sh file:device/marakana/alpha/vendorsetup.sh
Rebuild the lunch menu:
add_lunch_combo full_marakana_alpha-eng
$ source build/envsetup.sh
including device/marakana/alpha/vendorsetup.sh
including device/moto/stingray/vendorsetup.sh
including device/moto/wingray/vendorsetup.sh
including device/samsung/crespo4g/vendorsetup.sh
including device/samsung/crespo/vendorsetup.sh
including device/samsung/maguro/vendorsetup.sh
including device/samsung/toro/vendorsetup.sh
including device/samsung/tuna/vendorsetup.sh
including device/ti/panda/vendorsetup.sh
including sdk/bash_completion/adb.bash

Makefile Plumbing
12.1. The make system is complex - copy from samples to get started.
Create main product make file:device/marakana/alpha/AndroidProducts.mk
Create the main build file:device/marakana/alpha/full_alpha.mk
Copy boiler-plate files from generic:
PRODUCT_MAKEFILES := $(LOCAL_DIR)/full_alpha.mk
$(call inherit-product, $(SRC_TARGET_DIR)/product/languages_small.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/generic.mk)
# Discard inherited values and use our own instead.
PRODUCT_NAME := full_marakana_alpha
PRODUCT_DEVICE := alpha
PRODUCT_MODEL := Full Marakana Alpha Image for Emulator
include $(call all-makefiles-under,$(LOCAL_PATH))
$ cp build/target/board/generic/BoardConfig.mk \
device/marakana/alpha/.
$ cp build/target/board/generic/AndroidBoard.mk \
device/marakana/alpha/.
$ cp build/target/board/generic/device.mk \
device/marakana/alpha/.
$ cp build/target/board/generic/system.prop \
device/marakana/alpha/.

Generating Platform Signing Keys
13.1. To pass CTS, we must generate our own platform signing keys
Define our subject/issuer info:
Remove the existing keys (it does not hurt to back them up first!):
Generate the platform key:
Generate the shared key:
Generate the media key:
$ SIGNER="/C=US/ST=California/L=San Francisco/O=Marakana
Inc./OU=Android/CN=Android Platform Signer/[email protected]"
$ rm build/target/product/security/*.p*
$ echo | development/tools/make_key build/target/product/security/platform
"$SIGNER"
creating build/target/product/security/platform.pk8 with no password
Generating RSA private key, 2048 bit long modulus
....................+++
..........................................................+++
e is 3 (0x3)
$ echo | development/tools/make_key build/target/product/security/shared
"$SIGNER"
creating build/target/product/security/shared.pk8 with no password
Generating RSA private key, 2048 bit long modulus
................................................................................
..................+++
............+++
e is 3 (0x3)
$ echo | development/tools/make_key build/target/product/security/media
"$SIGNER"
creating build/target/product/security/media.pk8 with no password
Generating RSA private key, 2048 bit long modulus

Generate the testkey key:
Verify that our keys have been created:
Check that our specific subject/issuer has been used:
The build/target/product/security/.pk8 files are the private keys (.x509.pem are thecertificates) - keep them safe and secure - especially since we did not encrypt them!
...................+++
....................+++
e is 3 (0x3)
$ echo | development/tools/make_key build/target/product/security/testkey
"$SIGNER"
creating build/target/product/security/testkey.pk8 with no password
Generating RSA private key, 2048 bit long modulus
....................+++
................................................+++
e is 3 (0x3)
$ ls -1 build/target/product/security/*.p*
build/target/product/security/media.pk8
build/target/product/security/media.x509.pem
build/target/product/security/platform.pk8
build/target/product/security/platform.x509.pem
build/target/product/security/shared.pk8
build/target/product/security/shared.x509.pem
build/target/product/security/testkey.pk8
build/target/product/security/testkey.x509.pem
$ openssl x509 -noout -subject -issuer -in
build/target/product/security/platform.x509.pem
subject= /C=US/ST=California/L=San Francisco/O=Marakana
Inc./OU=Android/CN=Android Platform Signer/[email protected]
issuer= /C=US/ST=California/L=San Francisco/O=Marakana
Inc./OU=Android/CN=Android Platform Signer/[email protected]

Building Alpha Device
14.1. Let’s build Alpha - so far a vanilla Android.
Register the device with build system
Choose lunch menu
Compile the device
Run new device
$ source build/envsetup.sh
including device/marakana/alpha/vendorsetup.sh
…
$ lunch full_marakana_alpha-eng
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=4.0.3
TARGET_PRODUCT=full_marakana_alpha
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=IML74K
============================================
$ export USE_CCACHE=1
$ make -j10
…
Installed file list: out/target/product/alpha/installed-files.txt
Target system fs image:
out/target/product/alpha/obj/PACKAGING/systemimage_intermediates/system.img
Install system fs image: out/target/product/alpha/system.img

Verify build numberLook for the Build number property in System Settings→About phone screen.
$ emulator -avd Alpha \
-system out/target/product/alpha/system.img \
-ramdisk out/target/product/alpha/ramdisk.img

Marakana Alpha Custom Kernel

Android Stack - Kernel

Marakana Alpha Custom Kernel Steps
17.1. Not everyone is going to need a custom kernel - but we can have it.
Download and build kernel source
Copy kernel into our device folder
Enable our custom kernel in BoardConfig.mkdevice/marakana/alpha/BoardConfig.mk
Create a alpha.mk makefile for our common componentsdevice/marakana/alpha-common/alpha.mk
$ mkdir ~/kernel/
$ cd ~/kernel/
$ git clone https://android.googlesource.com/kernel/goldfish.git
$ cd goldfish/
$ git branch -a
$ git checkout -t remotes/origin/android-goldfish-2.6.29
$ make goldfish_armv7_defconfig ARCH=arm
$ make menuconfig
$ make -j10 ARCH=arm \
CROSS_COMPILE=/AOSP/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-
cp /path/to/kernel/arch/arm/boot/zImage device/marakana/alpha-common/kernel
…
TARGET_NO_KERNEL := false
…
MY_PATH := $(LOCAL_PATH)/../alpha-common
include $(call all-subdir-makefiles)
# Enable our custom kernel
LOCAL_KERNEL := $(MY_PATH)/kernel
PRODUCT_COPY_FILES += $(LOCAL_KERNEL):kernel

Include alpha.mk in main makefile full_alpha.mkdevice/marakana/alpha/full_alpha.mk
Rebuild the device and restart the device with:
Verify it worked
…
include device/marakana/alpha-common/alpha.mk
$ emulator -avd Alpha \
-kernel out/target/product/alpha/kernel \
-system out/target/product/alpha/system.img \
-ramdisk out/target/product/alpha/ramdisk.img
$ adb shell cat /proc/version
Linux version 2.6.29-marakana-example-gb0d93fb ([email protected]) (gcc version
4.4.0 (GCC) ) #5 Tue Jul 19 22:24:03 PDT 2011

Marakana Alpha Custom Lib

Android Stack - Native Libraries

Marakana Alpha Custom Lib Steps
20.1. From drivers to open source libraries, you likely need custom libraries.
Create home for shared libraries
Create shared libs makefiledevice/marakana/alpha-common/lib/Android.mk
Create folder for libmrknlog library
Create libmrknlog.h header filedevice/marakana/alpha-common/lib/libmrknlog/libmrknlog.h
Implement the library libmrknlog.c using ioctl() to talk to kerneldevice/marakana/alpha-common/lib/libmrknlog/libmrknlog.c
Create the Android.mk makefiledevice/marakana/alpha-common/lib/libmrknlog/Android.mk
$ mkdir device/marakana/alpha-common/lib/
include $(call all-subdir-makefiles)
mkdir device/marakana/alpha-common/lib/libmrknlog
...
extern int mrkn_flush_log();
extern int mrkn_get_total_log_size();
extern int mrkn_get_used_log_size();
...
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := libmrknlog.c
LOCAL_SHARED_LIBRARIES := libcutils libutils libc
LOCAL_MODULE := libmrknlog
LOCAL_PRELINK_MODULE := false

Register the library with alpha.mkdevice/marakana/alpha-common/alpha.mk
Test libmrknlog.so builds
include $(BUILD_SHARED_LIBRARY)
…
PRODUCT_PACKAGES += libmrknlog
$ make -j10 libmrknlog
…
target SharedLib: libmrknlog
(out/target/product/generic/obj/SHARED_LIBRARIES/libmrknlog_intermediates/LINKED
/libmrknlog.so)
target Non-prelinked: libmrknlog
(out/target/product/generic/symbols/system/lib/libmrknlog.so)
target Strip: libmrknlog (out/target/product/generic/obj/lib/libmrknlog.so)
Install: out/target/product/generic/system/lib/libmrknlog.so

Marakana Alpha Native Daemon

Android Stack - Native Daemons

Marakana Alpha Native Daemon Steps
23.1. It’s nice to have a native daemon look over your shoulder.
Create folder for binaries
Create Android.mk for binariesdevice/marakana/alpha-common/bin/Android.mk
Create daemon source file mrknlogd.cdevice/marakana/alpha-common/bin/mrknlogd/mrknlogd.c
Create Android.mk filedevice/marakana/alpha-common/bin/mrknlogd/Android.mk
Register mrknlogd with alpha.mk filedevice/marakana/alpha-common/alpha.mk
Create custom init.rc by using the default one
$ mkdir device/marakana/alpha-common/bin
$ mkdir device/marakana/alpha-common/bin/mrknlogd
include $(call all-subdir-makefiles)
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := mrknlogd.c
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../lib/libmrknlog/
LOCAL_SHARED_LIBRARIES := libmrknlog libc libcutils libutils
LOCAL_MODULE := mrknlogd
include $(BUILD_EXECUTABLE)
…
PRODUCT_PACKAGES += mrknlogd
$ cp system/core/rootdir/init.rc device/marakana/alpha-common/.

Register mrknlogd with init.rcdevice/marakana/alpha-common/init.rc
Include init.rc in our alpha.mk device builddevice/marakana/alpha-common/alpha.mk
Build the device
Verify it all works by restarting the device
…
# Marakana's custom log-flushing daemon
service mrknlogd /system/bin/mrknlogd 60
user system
group log
oneshot
…
# Copy our init.rc file over the existing one (since ours contains extra
changes)
PRODUCT_COPY_FILES += $(MY_PATH)/init.rc:root/init.rc
$ make -j10
…
Install system fs image: out/target/product/alpha/system.img
Installed file list: out/target/product/alpha/installed-files.txt
# (re)start the emulator
$ emulator -kernel out/target/product/alpha/kernel &
# wait for the emulator to finish
# check out our daemon
$ adb shell ls -l /system/bin/mrknlogd
-rwxr-xr-x root shell 5508 2011-07-13 02:25 mrknlogd
# check that it runs
$ adb shell ps | grep mrknlogd
system 37 1 1044 292 c00520f8 afd0bdac S /system/bin/mrknlogd
$ adb logcat | grep MRKN
I/MRKN Log Daemon( 37): Flushed log (1, 60 of 65536 bytes). Waiting 60 seconds
before the next flush.
I/MRKN Log Daemon( 37): Flushed log (2, 34406 of 65536 bytes). Waiting 60
seconds before the next flush.
I/MRKN Log Daemon( 37): Flushed log (3, 232 of 65536 bytes). Waiting 60

seconds before the next flush.
C
$ adb logcat -g
/dev/log/main: ring buffer is 64Kb (0Kb consumed), max entry is 4096b, max
payload is 4076b
# good :-)

Wrapping Native Lib with JNI

Wrapping Native Lib with JNI Steps
25.1. The glue for Java to talk to C and back.
Create directory structure for our JNI wrapper
Create top level Android.mk filesdevice/marakana/alpha-common/framework/Android.mk
device/marakana/alpha-common/framework/mrknlog_jni/Android.mk
Create Java Library LibLog.javadevice/marakana/alpha-common/\
framework/mrknlog_jni/java/com/marakana/android/lib/log/LibLog.java
Create test Main.javadevice/marakana/alpha-common/\
framework/mrknlog_jni/java/com/marakana/android/lib/log/Main.java
Create custom permissiondevice/marakana/alpha-common/framework/mrknlog_jni/java/com.marakana.android.lib.log.xml
Create Android.mk file for our JNI wrapper
$ mkdir device/marakana/alpha-common/framework
$ mkdir device/marakana/alpha-common/framework/mrknlog_jni
$ mkdir device/marakana/alpha-common/framework/mrknlog_jni/java
$ mkdir device/marakana/alpha-common/framework/mrknlog_jni/jni
include $(call all-subdir-makefiles)
include $(call all-subdir-makefiles)
<?xml version="1.0" encoding="utf-8"?>
<permissions>
<library name="com.marakana.android.lib.log"
file="/system/framework/com.marakana.android.lib.log.jar"/>
</permissions>

device/marakana/alpha-common/framework/mrknlog_jni/java/Android.mk
Create the JNI header file
Check that you got the right JNI headerdevice/marakana/alpha-common/framework/mrknlog_jni/jni/com_marakana_android_lib_log_LibLog.h
LOCAL_PATH := $(call my-dir)
# Build the library
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := com.marakana.android.lib.log
LOCAL_SRC_FILES := $(call all-java-files-under,.)
LOCAL_JAVA_LIBRARIES := core
LOCAL_NO_STANDARD_LIBRARIES := true
include $(BUILD_JAVA_LIBRARY)
# Build the documentation
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files) $(call all-subdir-html-files)
LOCAL_MODULE:= com.marakana.android.lib.log_doc
LOCAL_DROIDDOC_OPTIONS := com.marakana.android.lib.log
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_DROIDDOC_USE_STANDARD_DOCLET := true
include $(BUILD_DROIDDOC)
# Copy com.marakana.android.lib.log.xml to /system/etc/permissions/
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := com.marakana.android.lib.log.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
LOCAL_SRC_FILES := $(LOCAL_MODULE)
include $(BUILD_PREBUILT)
$ javah -jni \
-d device/marakana/alpha-common/framework/mrknlog_jni/jni/ \
-classpath
out/target/common/obj/JAVA_LIBRARIES/com.marakana.android.lib.log_intermediates/
classes.jar \
com.marakana.android.lib.log.LibLog
…

Implement the header file, wrapping calls to our libmrknlog shared librarydevice/marakana/alpha-common/\
framework/mrknlog_jni/jni/com_marakana_android_lib_log_LibLog.c
Create Android.mk filedevice/marakana/alpha-common/framework/mrknlog_jni/jni/Android.mk
Register this module with alpha.mk filedevice/marakana/alpha-common/alpha.mk
Build the device
JNIEXPORT void JNICALL Java_com_marakana_android_lib_log_LibLog_flushLog
(JNIEnv*, jclass);
…
JNIEXPORT jint JNICALL Java_com_marakana_android_lib_log_LibLog_getTotalLogSize
(JNIEnv*, jclass);
…
JNIEXPORT jint JNICALL Java_com_marakana_android_lib_log_LibLog_getUsedLogSize
(JNIEnv*, jclass);
…
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := com_marakana_android_lib_log_LibLog.c
LOCAL_C_INCLUDES += $(JNI_H_INCLUDE) $(LOCAL_PATH)/../../../lib/libmrknlog
LOCAL_SHARED_LIBRARIES := libmrknlog
LOCAL_MODULE := libmrknlog_jni
LOCAL_PRELINK_MODULE := false
include $(BUILD_SHARED_LIBRARY)
…
PRODUCT_PACKAGES += \
com.marakana.android.lib.log \
com.marakana.android.lib.log.xml \
libmrknlog_jni
$ make -j10
…
target Prebuilt: com.marakana.android.lib.log.xml
(out/target/product/alpha/obj/ETC/com.marakana.android.lib.log.xml_intermediates
/com.marakana.android.lib.log.xml)

Verify it works via our Main.main() test code
…
Install: out/target/product/alpha/system/lib/libmrknlog_jni.so
…
Install system fs image: out/target/product/alpha/system.img
Installed file list: out/target/product/alpha/installed-files.txt
# (re)start the emulator
$ emulator -kernel out/target/product/alpha/kernel &
# wait for the emulator to finish
# check out our Java library
$ adb shell ls -l /system/framework/com.marakana.android.lib.log.jar
-rw-r--r-- root root 1471 2011-07-11 00:01
com.marakana.android.lib.log.jar
# check out our Java library registry file
$ adb shell ls -l /system/etc/permissions/com.marakana.android.lib.log.xml
-rw-r--r-- root root 179 2011-07-10 23:57
com.marakana.android.lib.log.xml
# check out our JNI shared library
$ adb shell ls -l /system/lib/libmrknlog_jni.so
-rw-r--r-- root root 5296 2011-07-11 01:41 libmrknlog_jni.so
# check if our utility is doing what it is supposed to
$ adb logcat -g
/dev/log/main: ring buffer is 64Kb (33Kb consumed), max entry is 4096b, max
payload is 4076b
# now run our Java library's Main.main() by directly invoking the Dalvik VM
$ adb shell dalvikvm -cp /system/framework/com.marakana.android.lib.log.jar
com.marakana.android.lib.log.Main
Flushed log. Previously it was consuming 34346 of 65536 bytes
# check again
$ adb logcat -g
/dev/log/main: ring buffer is 64Kb (0Kb consumed), max entry is 4096b, max
payload is 4076b
$ adb shell dalvikvm -cp /system/framework/com.marakana.android.lib.log.jar
com.marakana.android.lib.log.Main
Flushed log. Previously it was consuming 217 of 65536 bytes
# good :-)

Marakana Alpha Service Interface

Android Stack - Framework

Marakana Alpha Service Interface Steps
28.1. Because other apps are going to want to use our service as well.
Create directory structure for our mrknlogservice
Create the interface LogService.aidl filedevice/marakana/alpha-common/\
framework/mrknlogservice/com/marakana/android/service/log/ILogService.aidl
Create LogManager.java proxy to our bound servicedevice/marakana/alpha-common/\
framework/mrknlogservice/com/marakana/android/service/log/LogManager.java
Expose LogManager.java as a Java librarydevice/marakana/alpha-common/framework/mrknlogservice/com.marakana.android.service.log.xml
Create Android.mk file for mrknlogservicedevice/marakana/alpha-common/framework/mrknlogservice/Android.mk
$ mkdir -p device/marakana/alpha-
common/framework/mrknlogservice/com/marakana/android/service/log
<?xml version="1.0" encoding="utf-8"?>
<permissions>
<library name="com.marakana.android.service.log"
file="/system/framework/com.marakana.android.service.log.jar"/>
</permissions>
LOCAL_PATH := $(call my-dir)
# Build the library
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := com.marakana.android.service.log
LOCAL_SRC_FILES := $(call all-java-files-under,.)
LOCAL_SRC_FILES += com/marakana/android/service/log/ILogService.aidl
LOCAL_JAVA_STATIC_LIBRARIES := android-common
LOCAL_JAVA_LIBRARIES := core
include $(BUILD_JAVA_LIBRARY)

Add it to alpha.mk filedevice/marakana/alpha-common/alpha.mk
Verify that the device builds okay
# Build the documentation
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files) $(call all-subdir-html-files)
LOCAL_MODULE:= com.marakana.android.service.log_doc
LOCAL_DROIDDOC_OPTIONS := com.marakana.android.service.log
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_DROIDDOC_USE_STANDARD_DOCLET := true
include $(BUILD_DROIDDOC)
# Copy com.marakana.android.service.log.xml to /system/etc/permissions/
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := com.marakana.android.service.log.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
LOCAL_SRC_FILES := $(LOCAL_MODULE)
include $(BUILD_PREBUILT)
…
PRODUCT_PACKAGES += \
com.marakana.android.service.log \
com.marakana.android.service.log.xml
$ make -j10 com.marakana.android.service.log
com.marakana.android.service.log.xml
…
target Prebuilt: com.marakana.android.service.log.xml
…
Install:
out/target/product/alpha/system/etc/permissions/com.marakana.android.service.log
.xml
…
Aidl: com.marakana.android.service.log <= device/marakana/alpha-
common/framework/mrknlogservice/com/marakana/android/service/log/ILogService.aid
l
…
target Jar: com.marakana.android.service.log
…
Install:

out/target/product/alpha/system/framework/com.marakana.android.service.log.jar
…

Marakana Alpha Service App

Android Stack - Services

Marakana Alpha Service App Steps
31.1. Register the service with the Service Manager so others can use it.
Create the directory structure for our code
Create main Android.mk filedevice/marakana/alpha-common/app/Android.mk
Create AndroidManifest.xml file for our server appdevice/marakana/alpha-common/app/MrknLogService/AndroidManifest.xml
Provide ILogServiceImpl.java implementation for our servicedevice/marakana/alpha-common/\
app/MrknLogService/src/com/marakana/android/logservice/ILogServiceImpl.java
Register LogServiceApp with ServiceManagerdevice/marakana/\ alpha-
common/app/MrknLogService/src/com/marakana/android/logservice/LogServiceApp.java
Create the Android.mk filedevice/marakana/alpha-common/app/MrknLogService/Android.mk
$ mkdir device/marakana/alpha-common/app
include $(call all-subdir-makefiles)
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under,src)
LOCAL_REQUIRED_MODULES := \
com.marakana.android.service.log \
com.marakana.android.lib.log
LOCAL_JAVA_LIBRARIES := \
com.marakana.android.service.log \
com.marakana.android.lib.log \
core \
framework
LOCAL_PACKAGE_NAME := MrknLogService
LOCAL_SDK_VERSION := current

Register our service app with alpha.mk filedevice/marakana/alpha-common/alpha.mk
Build the device
LOCAL_PROGUARD_ENABLED := disabled
LOCAL_CERTIFICATE := platform
include $(BUILD_PACKAGE)
…
PRODUCT_PACKAGES += MrknLogService
$ make -j10
…
Install: out/target/product/alpha/system/app/MrknLogService.apk
…
Install system fs image: out/target/product/alpha/system.img
Installed file list: out/target/product/alpha/installed-files.txt

Marakana Alpha Client App

Android Stack - Apps

Marakana Alpha Client App Steps
34.1. A demo client app - to make sure it all works.
Create directory structure for our MrknLogServiceClient app
Create LogActivity.javadevice/marakana/alpha/\
app/MrknLogServiceClient/src/com/marakana/android/logserviceclient/LogActivity.java
Create AndroidManifest.xml filedevice/marakana/alpha/app/MrknLogServiceClient/AndroidManifest.xml
Create Android.mk filedevice/marakana/alpha/app/MrknLogServiceClient/Android.mk
Register MrknLogServiceClient with main makefile full_alpha.xmldevice/marakana/alpha/full_alpha.mk
$ mkdir device/marakana/alpha/app/MrknLogServiceClient
$ mkdir device/marakana/alpha/app/MrknLogServiceClient/res
$ mkdir device/marakana/alpha/app/MrknLogServiceClient/res/values
$ mkdir device/marakana/alpha/app/MrknLogServiceClient/res/layout
$ mkdir device/marakana/alpha/app/MrknLogServiceClient/src
$ mkdir -p
device/marakana/alpha/app/MrknLogServiceClient/src/com/marakana/android/logservi
ceclient
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under,src)
LOCAL_JAVA_LIBRARIES := com.marakana.android.service.log
LOCAL_PACKAGE_NAME := MrknLogServiceClient
LOCAL_SDK_VERSION := current
LOCAL_PROGUARD_ENABLED := disabled
include $(BUILD_PACKAGE)
…
PRODUCT_PACKAGES += MrknLogServiceClient

Build entire device
Verify it all worksRun the MrknLogServiceClient app and try to flush the log.
$ make -j10
…
Install system fs image: out/target/product/alpha/system.img
Installed file list: out/target/product/alpha/installed-files.txt

Marakana Alpha SDK Add-On
35.1. Other developers may want to develop for our cool Alpha device as well.
Create directory structure
Create portrait layout backgroundWe took a standard one and just added our logo.
Create landscape layout backgroundSame as with the previous image, just add a logo.
$ mkdir device/marakana/alpha-sdk_addon/skins
$ cp -r sdk/emulator/skins/HVGA device/marakana/alpha-
sdk_addon/skins/MrknHvgaMdpi

Define hardware.ini filedevice/marakana/alpha-sdk_addon/hardware.ini
Create SDK Add-on manifest.ini filedevice/marakana/alpha-sdk_addon/manifest.ini
# Custom hardware options for the add-on.
# Properties defined here impact all AVD targeting this add-on.
# Each skin can also override those values with its own hardware.ini file.
vm.heapSize = 24
name=Alpha Add-On
vendor=Marakana
description=Marakana Alpha Add-on
api=10
revision=1
libraries=com.marakana.android.lib.log;com.marakana.android.service.log
com.marakana.android.lib.log=com.marakana.android.lib.log.jar;Marakana Log
Library
com.marakana.android.service.log=com.marakana.android.service.log.jar;Marakana
Log Service
skin=MrknHvgaMdpi

Define classes to be includeddevice/marakana/alpha-sdk_addon/alpha_sdk_addon_stub_defs.txt
Create main alpha_sdk_addon.mk makefile for Alpha SDK Add-ondevice/marakana/alpha-sdk_addon/alpha_sdk_addon.mk
+com.marakana.android.lib.log.*
-com.marakana.android.lib.log.Main
+com.marakana.android.service.log.*
# Include the common stuff
include device/marakana/alpha-common/alpha.mk
# List of modules to include in the the add-on system image
PRODUCT_PACKAGES += \
com.marakana.android.lib.log_doc \
com.marakana.android.service.log_doc \
# The name of this add-on (for the SDK)
PRODUCT_SDK_ADDON_NAME := marakana_alpha_addon
# Copy the following files for this add-on's SDK
PRODUCT_SDK_ADDON_COPY_FILES := \
$(LOCAL_PATH)/manifest.ini:manifest.ini \
$(LOCAL_PATH)/hardware.ini:hardware.ini \
$(call find-copy-subdir-files,*
,$(LOCAL_PATH)/skins/MrknHvgaMdpi,skins/MrknHvgaMdpi)
# Copy the jar files for the libraries (APIs) exposed in this add-on's SDK
PRODUCT_SDK_ADDON_COPY_MODULES := \
com.marakana.android.lib.log:libs/com.marakana.android.lib.log.jar \
com.marakana.android.service.log:libs/com.marakana.android.service.log.jar
PRODUCT_SDK_ADDON_STUB_DEFS := $(LOCAL_PATH)/alpha_sdk_addon_stub_defs.txt
# Define the name of the documentation to generate for this add-on's SDK
PRODUCT_SDK_ADDON_DOC_MODULE := \
com.marakana.android.service.log_doc
# Since the add-on is an emulator, we also need to explicitly copy the kernel to
images
PRODUCT_SDK_ADDON_COPY_FILES += $(LOCAL_KERNEL):images/kernel-qemu

Create main AndroidProducts.mk listing other makefilesdevice/marakana/alpha-sdk_addon/AndroidProducts.mk
Create top-level makefiledevice/marakana/alpha-sdk_addon/Android.mk
Build the SDK Add-on
Check that Marakana Alpha shows in Android SDK ManagerStart the Android SDK Manager to see all available Add-ons.
# This add-on extends the default sdk product.
$(call inherit-product, $(SRC_TARGET_DIR)/product/sdk.mk)
# The name of this add-on (for the build system)
# Use 'make PRODUCT-<PRODUCT_NAME>-sdk_addon' to build the an add-on,
# so in this case, we would run 'make PRODUCT-marakana_alpha_addon-sdk_addon'
PRODUCT_NAME := marakana_alpha_addon
PRODUCT_DEVICE := alpha
PRODUCT_MODEL := Marakana Alpha SDK Addon Image for Emulator
PRODUCT_MAKEFILES := $(LOCAL_DIR)/alpha_sdk_addon.mk
include $(call all-subdir-makefiles)
$ make -j10 PRODUCT-marakana_alpha_addon-sdk_addon
…
Packaging SDK Addon: out/host/linux-x86/sdk_addon/marakana_alpha_addon-
eng.student-linux-x86.zip

Create new AVD based on Marakana AlphaFrom the Android AVD Manager, create new AVD using Alpha as the target.

Verify the new AVD boots up with right ROM imageStart the new AVD. You should see all of the modifications we’ve done.


Remixing Android SummaryThank you!
Marko Gargenta & Marakana Team
@MarkoGargenta
Special thanks to Aleksandar (Sasa) Gargenta for providing most of the research on how toput together Marakana Alpha, properly.
Slides & video of this presentation is available at Marakana.com
(c) Marakana.com