Thursday, September 17, 2009

Fix syntax highlighter in the blogger template

Sep-17th - It seems syntax highlighter has updated, so my code snippet is in a mess again:(

Sep-30th:

Revert to R92. Change the template as following:


<link href='http://flash-host.com.br/blog/sh/SyntaxHighlighter.css' rel='stylesheet' type='text/css'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn-history/r92/trunk/Scripts/shCore.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn-history/r92/trunk/Scripts/shBrushCSharp.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn-history/r92/trunk/Scripts/shBrushXml.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn-history/r92/trunk/Scripts/shBrushPython.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn-history/r92/trunk/Scripts/shBrushJScript.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn-history/r92/trunk/Scripts/shBrushCpp.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn-history/r92/trunk/Scripts/shBrushBash.js'/>
<script language='javascript'>

dp.SyntaxHighlighter.BloggerMode();
dp.SyntaxHighlighter.HighlightAll('code');

</script>

Tuesday, July 7, 2009

Opencore logs and releases

1. Enable Opencore 2.0x logs:
1)At compilation time, add the marco ENABLE_PV_LOGGING=1
$ cd <android_home>
$ touch external/opencore/oscl/oscl/osclbase/src/pvlogger.h
$ make ENABLE_PV_LOGGING=1

2)At runtime, /sdcard/pvlogger.txt is used to specify enabled log level and related tags. (write 8 alone in it will enable all pv logs.) Below is extracted from external/opencore/android/android_logger_config.h:
/*
To configure logging at runtime, a file pvlogger.txt must be located in the sdcard.
The format for log level and logger tag in the file should be: "level,node". Note that there should be no space between log level and logger tag.
For example, pvlogger.txt can look like:
1,PVPlayerEngine
8,PVSocketNode
Above example means log the message level PVLOGMSG_ALERT for PVPlayerEngine and PVLOGMSG_DEBUG for PVSocketNode. See pvlogger.h for log level values.
*/


2. Enable Opencore 1.0 logs:
1)Change external/opencore/oscl/pvlogger/src/pvlogger.h:
/* Release mode-- No logging */
#define PVLOGGER_INST_LEVEL 0
---- Change this value to 5
2)Change external/opencore/android/thread_init.cpp:
#if 0 --------- Change this value to 1
PVLoggerAppender *appender = new
AndroidLogAppender
();
...
...

#endif

3)Rebuild android source.

PV Releases:
PV2.04: http://groups.google.com/group/android-framework/browse_thread/thread/ccec12e4fe876149/17254e4a88875a6b
PV2.02: http://groups.google.com/group/android-framework/browse_thread/thread/8b72bdad6ca508e/33033406a6b2e0d0
PV2.01: http://groups.google.com/group/android-framework/browse_thread/thread/5712f642dbee9398/f943ebc7ec02bb18
PV2.0: http://groups.google.com/group/android-framework/browse_thread/thread/92e10684c6f09e16/8df445f867c19f2e

Friday, April 24, 2009

World Reading Day

Below is a list of good software books:
Top 100 Best Software Engineering Books, Ever

Personally, I am a little surprised that Eric Evans' "Domain-Driven Design" ranks so low. And "Object Design: Roles Responsibilities and Collaborations" by Rebecca Wirfs-Brock is not on the list which is also worth reading:)

As someone commented, the list is more likely to be based on the popularity (good or not is really a subjective judgment which lacks the objective criteria:), but still, a good reference for reading.

(BTW: The original creator of the list has published another list of Top 50 New Software Development Books which may still need time proven:)

Saturday, April 4, 2009

Tips for debugging mediaserver

1. Add symbol file for dynamically loaded so, e.g. libopencore_asflocal.so
(1) Find where the module was loaded:
#cat /proc/<pid>/maps
a7c26000-a7c52000 r-xp 00000000 1f:06 1060 /system/lib/libopencore_asfloca
l.so
a7c52000-a7c54000 rw-p 0002c000 1f:06 1060 /system/lib/libopencore_asfloca
l.so


(2) Get the text section's offset within the module:
$objdump --section-headers out/target/product/generic/symbols/system/lib/libopencore_asflocal.so |grep text
6 .text 0001679c 0000e3c8 0000e3c8 0000e3c8 2**3

(3) Add this offset to the load address of the module to obtain the relocation address for the module's code: (0xa7c26000+0x0000e3c8 = 0xa7c343c8)
(gdb)add-symbol-file out/target/product/generic/symbols/system/lib/libopencore_asflocal.so 0xa7c343c8

2. Switch between threads inside mediaserver process
(gdb) info threads
(gdb) thread <id>

[1]Debugging with GDB
[2]Debugging Loadable Modules Using GDB
[3]Debugging programs with multiple threads

Saturday, March 14, 2009

3. Debug native process via ssh tunnel on Windows

By leveraging SSH tunnel, we can setup a gdb session from remote linux workstation to the connected device on Windows following below steps:

1. Config a Putty session with SSH tunnel enabled, adding a forwarded port from remote <port> -> <device ip>:<port> (e.g. R5039->192.168.16.2:5139)















2. Connect to the device on Windows via adb shell, then start gdb server to attach the specified native process. 
    $gdbserver <port> --attach <pid> #(e.g. $gdbserver :5139 --attach 65)

3. Connect to remote linux workstation with the session defined in step 1
    $cd ~/repo/android_root
    $./mygdb.sh <executable> <port>

Below is the source code of mygdb.sh:


#!/bin/sh
#This script is used to setup gdb to debug native processes on the device

if [ ! -f .repo/manifest.xml ]; then
echo "Please run gdb under android repo root directory!"
exit 1;
fi

rootdir=`pwd`
product="generic"
scriptdir=`dirname $0`
if [ $1 = "-p" ]; then
shift
product=$1
shift
elif [ -f $rootdir/product.cfg ]; then
product=`cat $rootdir/product.cfg`
elif [ -f $scriptdir/product.cfg ]; then
product=`cat $scriptdir/product.cfg`
fi

gdbtool="./codesourcery/toolchain/bin/arm-none-linux-gnueabi-gdb"
#gdbtool="./prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gdb"
exename="$1"
if [ -z "$exename" ] ; then
exename="mediaserver"
fi
portnum="$2"
if [ -z "$portnum" ] ; then
portnum=":5039"
fi

OUT_UNSTIPPED_DIR=$rootdir/out/target/product/$product/symbols/
if [ ! -z "$OUT_DIR" ]; then
OUT_UNSTIPPED_DIR=$OUT_DIR/target/product/$product/symbols/
fi
OUT_SO_SYMBOLS=$OUT_UNSTIPPED_DIR/system/lib/
OUT_BIN_SYMBOLS=$OUT_UNSTIPPED_DIR/system/bin/

echo >"$rootdir/gdbclient.cmds" "set solib-search-path $OUT_SO_SYMBOLS"
echo >>"$rootdir/gdbclient.cmds" "target remote $portnum"
echo >>"$rootdir/gdbclient.cmds" "set auto-solib-add on"
echo >>"$rootdir/gdbclient.cmds" "set sysroot $OUT_UNSTIPPED_DIR"
#echo >>"$rootdir/gdbclient.cmds" "set solib-absolute-prefix $OUT_UNSTIPPED_DIR"
echo >>"$rootdir/gdbclient.cmds" ""

$gdbtool -x "$rootdir/gdbclient.cmds" "$OUT_BIN_SYMBOLS/$exename"

[1]SSH tunnel explained
[2]Tunneling protocol
[3]gdbclient in envsetup.sh

Wednesday, March 4, 2009

Saturday, February 28, 2009

2. Draw a red block in c++


#define LOG_NDEBUG 0
#define LOG_TAG "NativeUITest"
#include <utils/Log.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>

#include <utils/IPCThreadState.h>
#include <utils/ProcessState.h>
#include <ui/SurfaceComposerClient.h>
#include <ui/Surface.h>
#include <ui/ISurfaceComposer.h>
#include "SkCanvas.h"
#include "SkDevice.h"

using namespace android;

static inline SkBitmap::Config convertPixelFormat(PixelFormat format)
{
/* note: if PIXEL_FORMAT_XRGB_8888 means that all alpha bytes are 0xFF,
then we can map to SkBitmap::kARGB_8888_Config, and optionally call
bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator)
*/
switch (format) {
case PIXEL_FORMAT_RGBA_8888: return SkBitmap::kARGB_8888_Config;
case PIXEL_FORMAT_RGBA_4444: return SkBitmap::kARGB_4444_Config;
case PIXEL_FORMAT_RGB_565: return SkBitmap::kRGB_565_Config;
case PIXEL_FORMAT_A_8: return SkBitmap::kA8_Config;
default: return SkBitmap::kNo_Config;
}
}

int main(int argc, char** argv)
{
sp<ProcessState> proc = ProcessState::self();
proc->startThreadPool();
int pid = getpid();
int nState = 0;
sp<SurfaceComposerClient> client = new SurfaceComposerClient;
sp<Surface> surface(client->createSurface(pid, 0, 176, 144, PIXEL_FORMAT_OPAQUE, ISurfaceComposer::eFXSurfaceNormal));

//set surface layer to INT_MAX
client->openTransaction();
//nState = surface->setSize(176, 144);
nState = surface->setPosition(100, 200);
nState = surface->setLayer(INT_MAX);
nState = surface->show();
client->closeTransaction();

//Start painting...
client->openTransaction();
Rect rect(0,0,176,144);
Region dirtyRegion(rect);
Surface::SurfaceInfo info;
status_t err = surface->lock(&info, &dirtyRegion);
if(err < 0)
{
client->closeTransaction();
IPCThreadState::self()->stopProcess();
return -1;
}
SkCanvas myCanvas;
SkCanvas* canvas = &myCanvas;
SkBitmap bitmap;
bitmap.setConfig(convertPixelFormat(info.format), info.w, info.h, info.bpr);
bitmap.setPixels(info.bits);
canvas->setBitmapDevice(bitmap);
canvas->clipRegion(dirtyRegion.toSkRegion());
int saveCount = canvas->save();
//paint hole
//canvas->drawColor(0, SkPorterDuff::kClear_Mode);
//paint a red block
canvas->drawARGB(255, 255, 0, 0);
canvas->restoreToCount(saveCount);
canvas->setBitmapDevice(SkBitmap());
nState = surface->unlockAndPost();
LOGI("surface->unlockAndPost, %d", nState);
client->closeTransaction();

sleep(10);
IPCThreadState::self()->stopProcess();
LOGI("quiting...");
return 0;
}

Thursday, February 26, 2009

Add syntax highlighter in Blogger

After adding syntax highlighter in my blog template, my previous blog looks much better now:)

Actually it's quite easy, just add following code snippet in the head section of blog template, right after <head> tag; then put <pre name='code' class='c++'>...</pre>around the code when you write blogs, everything will be ok:


<link href='http://syntaxhighlighter.googlecode.com/svn/trunk/Styles/SyntaxHighlighter.css' rel='stylesheet' type='text/css'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shCore.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushJava.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushCpp.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushJScript.js'/>
<script language='javascript' src='http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/shBrushXml.js'/>
<script language='javascript'>
window.onload = function () {
dp.SyntaxHighlighter.ClipboardSwf = 'http://syntaxhighlighter.googlecode.com/svn/trunk/Scripts/clipboard.swf';
dp.SyntaxHighlighter.BloggerMode();
dp.SyntaxHighlighter.HighlightAll('code');
}
</script>
<style type='text/css'>
.console {
background-color: black;
color: #ffffff;
font-family: courier;
}
</style>

Note:
1) I directly link to the js scripts in google code here, you can upload them to your web spaces and replace them;
2) Other languages' syntax support is also available from there;
3) Replace < > with &lt; and &gt; when you composite the blog.

Reference:
[1] SyntaxHighlighter Usage
[2] Blogger + SyntaxHighlighter

Tuesday, February 24, 2009

1. Native console app for video playback in Android

I spent some time for writing a native C++  app to test video in console, actually it seems to be much easier than I thought:) Below is the code snippet:

PS. I thought I should paint a hole above video surface as SurfaceView does, but it appears not necessary.


int main(int argc, char** argv)
{
LOGI("entering main...");
sp<ProcessState> proc = ProcessState::self();
proc->startThreadPool();
MediaPlayer mediaplayer;
if(argc > 1)
{
LOGI("set datasource: %s", argv[1]);
mediaplayer.setDataSource(argv[1]);
}
else
{
LOGI("set datasource: /data/test.mp4");
mediaplayer.setDataSource("/data/test.mp4");
}

LOGI("create SurfaceComposerClient");
int pid = getpid();
int nState = 0;
sp<SurfaceComposerClient> videoClient = new SurfaceComposerClient;

LOGI("create video surface");
sp<surface> videoSurface(videoClient->createSurface(pid, 0, 176, 144, PIXEL_FORMAT_OPAQUE, ISurfaceComposer::eFXSurfaceNormal|ISurfaceComposer::ePushBuffers));
videoClient->openTransaction();
//nState = videoSurface->setSize(176, 144);
//LOGI("videosurface->setSize, %d", nState);
//nState = videoSurface->setPosition(0, 0);
//LOGI("videosurface->setPosition, %d", nState);

//set toppest z-order
nState = videoSurface->setLayer(INT_MAX);
LOGI("videosurface->setLayer, %d", nState);
nState = videoSurface->show();
LOGI("videosurface->show, %d", nState);
videoClient->closeTransaction();

LOGI("set video surface to player");
mediaplayer.setVideoSurface(videoSurface);

status_t retCode = mediaplayer.prepare();
if(retCode < 0)
{
LOGE("prepare failed: %d\n", retCode);
IPCThreadState::self()->stopProcess();
return -1;
};

mediaplayer.start();
for(int i=0; i < 10; i++)
{
sleep(1);
LOGI("playing, i=%d\n", i);
}
mediaplayer.reset();
LOGI("quiting...");

//close binder fd, still need waiting for all binder threads exit?
IPCThreadState::self()->stopProcess();
return 0;
}

Android

It has been nearly 4 months since my employer changed its strategy to Android platform. As I am getting familiar with the new platform, I will record related tips I've learned in the blog:) And i hope it can also be helpful for others when its content gets richer...