Showing posts with label android. Show all posts
Showing posts with label android. Show all posts

6/22/2012

Is Gadget frame work supported and how to enable Gadget framework?

Q) Is gadget framework supported on Android Eclair?
Ans) Yes, Gadget framework is supported on the Android éclair



Q) How to check whether Gadget framework is enabled or not?

Ans) There are two frameworks for USB device driver in Android. One is Gadget framework and the other is Function framework.

Android Cupcake and Donut baselines use Function framework.



Android éclair have Gadget framework enabled by default. OEMs can check the below flags for their reference.

If gadget frame is enabled following flags are defined in the .config file of the chipset.

1) USB_MSM_OTG_72K(Device Drivers-> USB support -> OTG Support for Qualcomm On-chip USB controller).

2) CONFIG_USB_GADGET(Drivers-> USB support -> USB Gadget support ).

3) USB_GADGET_MSM_72K(Drivers-> USB support -> USB Gadget support -> USB peripheral Controller as MSM 72k USB controller).

4) CONFIG_USB_ANDROID(Drivers-> USB support -> USB Gadget support -> USB Gadget Drivers as Android Gadget).

5) CONFIG_USB_ANDROID_DIAG (select Diag function driver).

6) CONFIG_USB_ANDROID_CDC_ECM

7) CONFIG_USB_F_SERIAL

8) CONFIG_MODEM_SUPPORT

9) CONFIG_USB_CSW_HACK



Note: If gadget frame work is enabled, function frame work should to be disabled. Please check that flag CONFIG_USB_FUNCTION undefined or not.

Go to Device Drivers-> USB support -> USB Function support -> [ ] Support for USB Function drivers.(Exclude this)

Exclude this option in the kernelconfig.

2/09/2012

androidscreencast - Desktop app to control an android device remotely


Control an Android device remotely

androidscreencast is a free and simple to use desktop app for controlling an Android device remotely using a mouse and keyboard. 

androidscreencast has been developed using Java and it should work on Mac OS X, Windows and Linux with any Android device. 
Usage
Connect your Android device through USB cable and ensure it's detected with "adb devices". Run androidscreencast. You can launch it by typing "javaws <jnlp file>" from a command line.


If mouse/keyboard control doesn't work, open a command line and type :
  • adb shell
  • su
  • chmod 777 /data/dalvik-cache
  • cd /data/dalvik-cache
  • chmod 777 ./

Here are some key features of "androidscreencast":

・ Mouse and keyboard control FOR ROOTED DEVICES ONLY
・ Landscape mode (right click)
・ Video recording
・ Basic file browser
Requirements:

・ 
Android SDK
・ Java 1.5 or later
Limitations:

・ Slow refresh rate (about 4-5 fps)
・ Not all keycodes are mapped.


Command-line access

Get a local copy of the androidscreencast repository with this command:
git clone https://code.google.com/p/androidscreencast/

Android Board Bring-up


Boot Architecture on MSM™



ARM9™/AMSS boot
On-chip PBL
qcsbl.mbn
oemsbl.mbn
amss.mbn
–
Configures initial hardware config
(TLMM GPIO Configuration)
–
Configures modem's
multiprocessor subsystem
(SMEM, SMD, RPC)
–
Modem automatically connects to 3G network
Application processor/Linux boot
Android Bootloader
–
In /bootable/bootloader/legacy
Linux OS image
–
Mounts system and user file system
–
Starts up Android components via system/core/rootdir, starts up initial Dalvik process

Boot Architecture on MSM (cont.)

When power is applied to MSM, mARM executes the Primary Boot Loader (PBL) from on-chip ROM
PBL loads Qualcomm Secondary Boot Loader (QCSBL) into memory and transitions to secondary boot stage
System fully boots after QCSBL execution and enters operational software download mode
Modem image is loaded on mARM
Applications boot image, i.e., Android bootloader, is loaded into memory for aARM execution, which continues loading Android OS

Boot Architecture on QSD

ARM9™/AMSS boot
On-chip PBL
dbl.mbn/fsbl.mbn
osbl.mbn
amss.mbn
–
Configures initial hardware config
(TLMM GPIO Configuration)
–
Configures modem's
multiprocessor subsystem
(SMEM, SMD, RPC)
–
Modem automatically connects
to 3G network
Application processor/Linux boot
Android Bootloader
–
In bootable/bootloader/legacy
Linux OS image
–
Mounts system and user file system
–
Starts up Android components via system/core/rootdir, starts up initial Dalvik process

Android Boot Architecture

Android Bootloader Configuration~

Android Boot Architecture

Android Bootloader

For MSM7xxx and QSD, modem processor plays master role and handles memory configuration and clock/voltage setting for entire system
Android bootloader entry point (in /android/bootable/bootloader/legacy/usbloader/main.c)
Initialize ARM11 clock speed from TCXO to 600 MHz
Create partition table and initialize basic peripherals, such as UART, keypad, panel, USB, and flash controller
Parse or generate ATAGs
Load kernel and hand over to kernel init code
Handle image download, if needed

Bootloader File Structure

Bootloader located in:
/android/bootable/bootloader/legacy/usbloader
Bootloader libraries come from three categories:
Generic
Architecture
Board

Bootloader File Structure –Generic Category

Generic category contains code useful to any bootloader
Common bootloader libraries and base architectures
bootable/bootloader/legacy/include/boot/*.*
bootable/bootloader/legacy/libboot/*.*
bootable/bootloader/legacy/libc/*.*
bootable/bootloader/legacy/arch_armv6/*.*
Generated library and object located at:
out/target/product/msm7627_surf/obj/STATIC_LIBRARIES/libboot_intermediates/libboot.a
out/target/product/msm7627_surf/obj/STATIC_LIBRARIES/libboot_c_intermediates/libboot_c.a
out/target/product/msm7627_surf/obj/STATIC_LIBRARIES/libboot_arch_armv6_intermediates/libboot_arch_armv6.a

Bootloader File Structure –Architecture Category

Architecture category contains code useful to specific CPU, system-on-chip, etc.
Libraries and base architectures –Headers
bootable/bootloader/legacy/include/msm7k/*.*
bootable/bootloader/legacy/ arch_msm7k /*.*
Generated library and object file located at:
out/target/product/msm7627_surf/obj/STATIC_LIBRARIES/libboot_arch_msm7k_intermediates/libboot_arch_msm7k.a

Bootloader File Structure –Board Category

Board category contains code useful to a single, specific device
Libraries and base architectures –Configuration
vendor/qcom/msm7627_surf/*.*
vendor/qcom/msm7627_surf/boot/*.*
Generated library and object file located at:
out/target/product/msm7627_surf/obj/STATIC_LIBRARIES/libboot_board_surf_intermediates/libboot_board_surf.a

Bootloader File Structure –Board Configuration

The BoardConfig.mk defines important build variables:
TARGET_BOOTLOADER_LIBS := \libboot_board_surf \libboot_arch_msm7k\libboot_arch_armv6
TARGET_BOOTLOADER_LINK_SCRIPT := \vendor/qcom/$(TARGET_PRODUCT)/boot/boot.ld
BOARD_KERNEL_CMDLINE := mem=203M console=ttyMSM2,115200n8 androidboot.hardware=qcom

Bootloader Configuration

The following primary files require modification for SURF boards:
vendor/qcom/msm7627_surf/boot/board.c –Defines flash partitions and atags, provides board-specific initialization
vendor/qcom/msm7627_surf/boot/panel.c –Panel driver for outputting console messages
vendor/qcom/msm7627_surf/boot/keypad.c –Keypad driver for hot-key controlling
arch_msm7k/android/nand.c –Flash driver for NAND devices
arch_msm7k/hsusb.c –USB driver for fast boot
arch_msm7k/clock.c –Clock driver for setting frequency of ARM11 and AHB
arch_msm7k/uart.c –Serial port driver
arch_msm7k/gpio.c –GPIO driver for bootloader
Note:For QSD, similar modifications would be made under the appropriate QSD architecture subdirectory.

Flash Layout –board.c

Flash partition table (unit –block); the partition in PTABLE must refer to allocation in /AMSS/products/7600/tools/headergen/partition.c
ptentry PTABLE[] = {
{
.start = 300,
.length = 40,
.name = "boot",
},
{
.start = 356,
.length = 512,
.name = "system"
},
{
.start = 868,
.length = 155 + 1024,
.name = "userdata",
},
{
.name = "",
},
};
Partition table
Range
Android partitions
0:APPSBL
230 –233
(1 MB)
Android
Bootloader
0:APPS +
0:FTL +
0:EFS2APPS
300 –339
(5 MB)
boot (kernel)
356 –867
(64 MB)
system
868 –2046
(147 MB)
user data

Command Line –board.c

Use Linux kernel command line (default kernel command line) or specify command line in BoardConfig.mk
const char *board_cmdline(void)
{
return "mem=201M console=ttyMSM2,115200n8";
}
Board machine type
unsigned board_machtype(void)
{
return 1439;
}
To register machine type, see [R1]

Keypad Configuration –keypad.c

android/bootable/bootloader/legacy/arch_msm7k/keypad.c
Configure GPIO for keypad
static unsigned int halibut_row_gpios[] = { 31, 32, 33, 34, 35, 41 };
static unsigned int halibut_col_gpios[] = { 36, 37, 38, 39, 40 };
Configure special key to stop booting Linux
–
The following example shows two different stop boot key mappings used by two different targets –SURF and FFA
static unsigned int halibut_key_map[] = {
[11] = BOOT_KEY_CONTINUE_BOOT, /* FA on SURF, B on FFA */
[23] = BOOT_KEY_STOP_BOOT, /* FB on SURF */
[27] = BOOT_KEY_STOP_BOOT, /* 2 on FFA */
};
On SURF, pressing the [FB] key will stop booting Linux and the system will enter Fastboot mode; the FFA's special key is [2]

Keypad Configuration –keypad.c (cont.)

Register keypad information
static gpio_keypad_info halibut_keypad = {
.output_gpios = halibut_row_gpios,
.input_gpios = halibut_col_gpios,
.noutputs = ARRAY_SIZE(halibut_row_gpios),
.ninputs = ARRAY_SIZE(halibut_col_gpios),
.key_map = halibut_key_map,
.settle_time = 5000,
.polarity = 0,
.drive_inactive_outputs = 1
};

Panel Configuration –panel.c

The following interfaces are implemented for the Toshiba VGA panel on SURF:
panel_init( ) –Panel ID detection
panel_poweron( ) –Power-on panel
panel_backlight( ) –Control backlight of panel
The MDDI console is implemented to output messages
bootable/bootloader/legacy/arch_msm7k/mddi_console.c
console_init()
console_putc()
console_clear()

Bootloader Framebuffer

console_putc() calls drawglyph() to draw the character on LCD
drawglyph(pixels + cy * 12 * fb_width + cx * 6, FGCOLOR,fb_width, font5x12 + (c -32) * 2);
The font5x12[] is character pattern file
unsigned font5x12[] = {0x00000000, 0x00000000,0x08421080, 0x000200840x00052940, 0x00000000,0x15f52800, 0x0000295f,0x1c52f880, 0x00023e94,0x08855640, 0x0004d542,.......}

Bootloader Framebuffer (cont.)

Default resolution in bootloader is 800 (fb_width) x 480(fb_height)
Color format –565RGB
bit[0:4] –Blue
bit[5:10] –Green
bit[11:15] –Red
Example to splash RGB color on LCD
void splash_image(){
unsigned short *dst = mddi_framebuffer();
unsigned short color,rgb[3] = {0xf800, 0x07E0, 0x001f};
unsigned j,k;
for (j = 0; j < fb_height; j++) {
if ( !(j % (fb_height/3) ) )
color = rgb[ j/(fb_height/3) ];
for (k = 0; k < fb_width; k++ )
*dst++ = color;
}
console_flush();
}

UART Configuration –uart.c

bootable/bootloader/legacy/arch_msm7k/uart.c
uart_init() –Configure UART base address and init UART configuration, uart_init (n) , n = 0 (UART1), 1 (UART2), 2 (UART3)
In uart_init()uwr(UART_CSR_115200, UART_CSR); // to change baud rate
uart_getc() –Get input character from console
uart_putc() –Send output character to console
uart_put() –Send output string to console

USB Driver

bootable/bootloader/legacy/arch_msm7k/hsusb.c
Supports fastboot protocol to download image
Supports Fastboot mode
Protocol defined over USB
Used for flashing Android bootloader, system image, and file system
Mode normally triggered by special key sequence upon startup
Fastboot application
–
Source files –system/core/fastboot
–
Fastboot available on Linux, Mac OSX, and Windows versions; for information regarding how to build the fastboot application, refer to [Q3]
–
Flashes new Android code much faster than JTAG

Bootloader MSM7x27 Clock Configuration –clock.c

bootable/bootloader/legacy/arch_msm7k/clock.c
ARM11 core clock source is determined by A11S_CLK_CNTL (0xC0100100) CLK_SRC1_SEL[12:14] or CLK_SRC0_SEL[4:6] and A11S_CLK_SEL (0xC0100104) CLK_SEL_SRC1N0[0]
MSM7x27 pll speed of Dual mode frequency plan

Bootloader MSM7x27 Clock Configuration –clock.c (cont.)

arm11_clock_init() increases the ARM11 core speed from 19.2 MHz to 600 MHz
C = > A11S_CLK_CNTL, S => A11S_CLK_SEL
C,(CLK_SRC_TCXO << 12) | (DIV_1 << 8) | \
(CLK_SRC_TCXO << 4) | (DIV_1)),
S, ((DIV_4 << 1) | (CLK_SRC0)),
ARM11 : 19.2 MHz / 1 = 19.2 MHz
C, (CLK_SRC_TCXO << 12) | (DIV_1 << 8) | \
(CLK_SRC_PLL2 << 4) | (DIV_5)),
S, ((DIV_4 << 1) | (CLK_SRC1)),
ARM11 : 1200 MHz / 5 = 240 MHz
C, (CLK_SRC_PLL2 << 12) | (DIV_3 << 8) | \
(CLK_SRC_PLL2 << 4) | (DIV_5)),
S, ((DIV_4 << 1) | (CLK_SRC0)),
ARM11 : 1200 MHz / 3 = 400 MHz
C, (CLK_SRC_PLL2 << 12) | (DIV_3 << 8) | \
(CLK_SRC_PLL2 << 4) | (DIV_2)),
S, ((DIV_3 << 1) | (CLK_SRC1)),
ARM11 : 1200 MHz / 2 = 600 MHz

Bootloader QSD Clock Configuration –clock.c

bootable/bootloader/legacy/arch_qsd8k/clock.c
Scorpion core clock source is determined by SPSS_CLK_SEL (0xAC100104) register [2:1]; reset clock source is AXI Bus Clock
arm11_clock_init() sets the Scorpion core clock source to 01: Unbuffered Snapdragon core processor PLL
val = readl(A11S_CLK_SEL);
val &= ~(0x3 << 1); // reset the clock source
val |= (1 << 1);//set clock source to SPLL
writel(val, A11S_CLK_SEL);
The formula for SPLL is CLOCK = TCXO * L * 2, and the value of L can be configured in PLL_FSM_CTL_EXT(0xA8800010)[8:3]
val = readl(SCPLL_CTLE);
val &= ~(0x3F << 3);
val |= (0x14 << 3); //Use 0x1A instead of 0x14 for 998 MHz
writel(val, SCPLL_CTLE); //19.2 MHz*20*2=768 MHz, 19.2 MHz*26*2=998 MHz

Android Images

Output folder is android/out/target/product/msm7627_surf
usbloader –Android bootloader; for compliance with MIBIB architecture, a header is needed
–
MSM7K –appsboot.mbn (usbloader) and appsboothd.mbn
–
QSD8K –appsboot.mbn (40 bytes header + usbloader)
boot.img –Image containing (boot header + Linux kernel + ramdisk/rootfs)
system.img –Image containing Android user space applications and libraries, including libc.

Android Images –Bootimage Header

struct boot_img_hdr {
unsigned char magic[BOOT_MAGIC_SIZE];
unsigned kernel_size; /* size in bytes */
unsigned kernel_addr; /* physical load addr 0x10008000 */
unsigned ramdisk_size; /* size in bytes */
unsigned ramdisk_addr; /* physical load addr 0x11000000 */
unsigned tags_addr; /* physical addr for kernel tags
0x10000100 */
unsigned page_size; /* flash page size we assume */
unsigned unused[2]; /* future expansion: should be 0 */
unsigned char cmdline[BOOT_ARGS_SIZE];
unsigned id[8]; /* timestamp / checksum / sha1 / etc */
}

Android Kernel Configuration~

Android Kernel Configuration

Kernel Boot Sequence

Kernel initializing procedure
zImage decompression
–
/kernel/arch/arm/boot/compressed/head.S
ARM architecture specific kernel code
–
/kernel/arch/arm/kernel/head.S
–
/kernel/arch/arm/kernel/head-common.S
Processor-independent kernel code
–
/kernel/init/main.c
–
start_kernel()

Memory Map Requirements of Linux Kernel on MSM

Kernel physical memory start address recommended on 2 MB alignment
In file /kernel/arch/arm/kernel/head.S
#if (PHYS_OFFSET & 0x001fffff)
#error "PHYS_OFFSET must be at an even 2MiB boundary!"

12/30/2011

How to backup the user info in android device

#!/system/bin/sh
GetBackupList() {
    RAW_LIST=`grep '<package' /data/system/packages.xml | grep "$APPS_DIR"`
    COUNT=`echo "$RAW_LIST" | wc -l`
    while [ "$COUNT" -gt 0 ];do
        BACKUP=`echo "$RAW_LIST" | sed -n $COUNT"p" | cut -d' ' -f2 | cut -d'=' -f2 | sed 's/"//g'`
        BACKUP=$BACKUP"|"`echo "$RAW_LIST" | sed -n $COUNT"p" | cut -d' ' -f3 | cut -d'=' -f2 | sed 's/"//g'`
        echo $BACKUP
        COUNT=$(($COUNT-1))
    done
}
FILE_PREFIX="recback"
DEF_BACKUP_PATH="/sdcard"
TMP_DIR="/data/recback_dir"
TMP_FILE="$TMP_DIR/recback.tmp"
WIFI_CONF="/data/misc/wifi/wpa_supplicant.conf"
APPS_DIR="/data/app"
DATA_DIR="/data/data"
TIMEOUT="10"
# the providers which will be backup or restored
PROVIDERS="
com.android.providers.calendar
com.android.providers.telephony
com.android.providers.contacts
com.android.providers.settings
"
if [ ! -d "$TMP_DIR" ];then
    mkdir $TMP_DIR
fi
if [ "$1" == "-r" ];then
    shift
    if [ -z "$1" ];then
        echo "Expect parameter: Need to specify the backup file"
        return 1
    fi
    if [ ! -r "$1" ];then
        echo "Expect a readable backup file"
        return 1
    fi
    BACKUP_FILE="$1"
    echo "Restoring..."
    GetBackupList > "$TMP_FILE"
    # ========= Restore APKs =============
    TAR_APKS=`tar -tvf $BACKUP_FILE | grep '.apk' | sed 's/[ ][ ][ ]*/ /g' | \
                    cut -d' ' -f6`
    # Remove old apks and data
    for TAR_APK in $TAR_APKS;do
        # To avoid the name of *-1.apk
        APK_REAL_NAME=${TAR_APK%.*}  # exclude the extension name
        if [ $(echo ${APK_REAL_NAME##*-} | grep -E "[^0-9]" -v -c) -ne 0 ];then
            # This case means the file name is formatted as *-[0-9] with the
            # numbered postfix, so we should change the name to real name
            APK_REAL_NAME=${APK_REAL_NAME%-*}  # exclude the numbered postfix
        fi
        if [ -f "/$APK_REAL_NAME"-*.apk ];then
            APK_DATA_PATH="$DATA_DIR/"`cat "$TMP_FILE" | grep "$APK_REAL_NAME" | \
                             cut -d'|' -f1`
            if [ -d "$APK_DATA_PATH" ];then
                rm -r $APK_DATA_PATH
            fi
            rm "/$APK_REAL_NAME"-*.apk
        fi
    done
    PRE_CD=`pwd`
    cd $TMP_DIR
    for TAR_APK in $TAR_APKS;do
        tar -xvf $BACKUP_FILE $TAR_APK
        # To avoid the name of *-1.apk
        APK_REAL_NAME=${TAR_APK%.*}  # exclude the extension name
        if [ $(echo ${APK_REAL_NAME##*-} | grep -E "[^0-9]" -v -c) -ne 0 ];then
            # This case means the file name is formatted as *-[0-9] with the
            # numbered postfix, so we should change the name to real name
            APK_REAL_NAME=${APK_REAL_NAME%-*}  # exclude the numbered postfix
            mv $TAR_APK $APK_REAL_NAME".apk"
            TAR_APK=$APK_REAL_NAME".apk"
        fi
        cp -f $TAR_APK "$APPS_DIR"    # install the apk
        rm $TAR_APK
        PKG_NAME=`grep '<package' /data/system/packages.xml | grep "$TAR_APK" | \
                        cut -d' ' -f2 | cut -d'=' -f2 | sed 's/"//g'`
        NATIVE_LIB=`grep '<package' /data/system/packages.xml | grep "$TAR_APK" | \
                        cut -d' ' -f4 | cut -d'=' -f2 | sed 's/"//g'`
        TIMEOUT="10"
        while [ -z "$PKG_NAME" ] || [ -z "$NATIVE_LIB" ];do
            echo "wait system update $PKG_NAME ..."
            sleep 1
            PKG_NAME=`grep '<package' /data/system/packages.xml | grep "$TAR_APK" | \
                        cut -d' ' -f2 | cut -d'=' -f2 | sed 's/"//g'`
            NATIVE_LIB=`grep '<package' /data/system/packages.xml | grep "$TAR_APK" | \
                        cut -d' ' -f4 | cut -d'=' -f2 | sed 's/"//g'`
            if [ $TIMEOUT -gt 0 ];then
                TIMEOUT=$(($TIMEOUT-1))
            else
                rm "/$TAR_APK"
                break
            fi
        done
        if [ -n "$PKG_NAME" ];then
            DATA_OWN=`ls -l $DATA_DIR | grep "$PKG_NAME" | sed 's/\t/ /g' | \
                          sed 's/[ ][ ][ ]*/ /g' | cut -d' ' -f2`
            DATA_GROUP=`ls -l $DATA_DIR | grep "$PKG_NAME" | sed 's/\t/ /g' | \
                          sed 's/[ ][ ][ ]*/ /g' | cut -d' ' -f3`
            if [ -z "$DATA_OWN" ] || [ -z "$DATA_GROUP" ];then
                BEGIN_INDEX="5"
                while [ $(echo $DATA_OWN | grep "userId" -c) -eq 0 ] && \
                      [ $(echo $DATA_OWN | grep "sharedUserId" -c) -eq 0 ];do
                    DATA_OWN=`grep '<package' /data/system/packages.xml | \
                                    grep "$TAR_APK" | cut -d' ' -f"$BEGIN_INDEX"`
                    BEGIN_INDEX=$(($BEGIN_INDEX+1))
                done
                DATA_OWN=`echo $DATA_OWN | cut -d'=' -f2 | sed 's/"//g' | sed 's/\>//g'`
                DATA_GROUP="$DATA_OWN"
            fi
           
            echo "tar $BACKUP_FILE data/data/$PKG_NAME"
            tar -xvf $BACKUP_FILE "data/data/$PKG_NAME"
            echo "Copy data/data/$PKG_NAME"
            if [ -d "$DATA_DIR/$PKG_NAME/lib" ];then
                rm -r "data/data/$PKG_NAME/lib"
            fi
            cp -rf "data/data/$PKG_NAME" "$DATA_DIR/"
            rm -r "data/data/$PKG_NAME"    # delete immediately for more free space

            echo "pkgname: $PKG_NAME | lib: $NATIVE_LIB | own: $DATA_OWN | group: $DATA_GROUP"
            # Get each package data file and change the own permission to current apk
            PKG_DATA_FILES=`find $DATA_DIR/$PKG_NAME`
            chown $DATA_OWN"."$DATA_GROUP $PKG_DATA_FILES
            PKG_LIB_FILES=`find $NATIVE_LIB`
            chown "system.system" $PKG_LIB_FILES
        else
            # need to do sth?
            echo "ERROR: install $TAR_APK failed, PKG_NAME null"
        fi
    done
    # ========= End of restore APKs =============
    # ========= Restore Wifi configuration =============
    if [ ! -d "/data/misc" ];then
        mkdir /data/misc
    fi
    if [ ! -d "/data/misc/wifi" ];then
        mkdir /data/misc/wifi
    fi
    tar -xvf $BACKUP_FILE "data/misc/wifi/wpa_supplicant.conf"
    cp -f data/misc/wifi/wpa_supplicant.conf /data/misc/wifi/
    chown "wifi.wifi" /data/misc/wifi/wpa_supplicant.conf
    # ========= End of restore Wifi configuration =============
    # ========= Restore Providers =============
    # backup origin providers
    PROVIDER_LIST=""
    for PROVIDER in $PROVIDERS;do
        if [ -d "$DATA_DIR/$PROVIDER" ];then
            PROVIDER_LIST="$PROVIDER_LIST $DATA_DIR/$PROVIDER"
        else
            echo "ERROR: the provider [$PROVIDER] not existed"
        fi
    done
    tar -cvf $DEF_BACKUP_PATH"/providers_"$TIME_STAMP".tar" $PROVIDER_LIST
    TAR_PROVIDERS=`tar -tvf $BACKUP_FILE | \
                        grep 'com.android.providers.*/databases/' | \
                        grep "^d" | sed 's/[ ][ ][ ]*/ /g' | cut -d' ' -f6`
    for TAR_PROVIDER in $TAR_PROVIDERS;do
        tar -xvf $BACKUP_FILE $TAR_PROVIDER
        if [ ! -d "/$TAR_PROVIDER" ];then
            echo "skipped /$TAR_PROVIDER"
            continue
        fi
       
        DATA_OWN=`ls -l /$TAR_PROVIDER | head -n1 | sed 's/\t/ /g' | \
                      sed 's/[ ][ ][ ]*/ /g' | cut -d' ' -f2`
        DATA_GROUP=`ls -l /$TAR_PROVIDER | head -n1 | sed 's/\t/ /g' | \
                      sed 's/[ ][ ][ ]*/ /g' | cut -d' ' -f3`
        echo "Copy $TAR_PROVIDER"
        cp -rf $TAR_PROVIDER/* "/$TAR_PROVIDER"
        DATABASES_FILES=`find /$TAR_PROVIDER`
        chown "$DATA_OWN.$DATA_GROUP" $DATABASES_FILES
        rm -r $TAR_PROVIDER
    done
   
    # ========= End of restore Providers =============
    rm "$TMP_FILE"
    cd "$PRE_CD"
elif [ "$1" == "-b" ];then
    echo "Begin backup: $TIME_STAMP"
    GetBackupList > "$TMP_FILE"
    BACKUP_LIST=`cat "$TMP_FILE" | cut -d'|' -f1 | sed 's/^/\/data\/data\//g'`
    PROVIDER_LIST=""
    for PROVIDER in $PROVIDERS;do
        if [ -d "$DATA_DIR/$PROVIDER/databases" ];then
            PROVIDER_LIST="$PROVIDER_LIST $DATA_DIR/$PROVIDER/databases"
        else
            echo "ERROR: the provider [$PROVIDER] not existed"
        fi
    done
   
    TIME_STAMP=`date "+%y%m%d%H%M%S"`

    if [ ! -f "$WIFI_CONF" ];then
        WIFI_CONF=""
    fi
    if [ ! -d "$APPS_DIR" ];then
        APPS_DIR=""
    fi
    PRE_CD=`pwd`
    cd "/data"
    tar -cvf $DEF_BACKUP_PATH"/"$FILE_PREFIX$TIME_STAMP".tar" \
               $BACKUP_LIST $PROVIDER_LIST $WIFI_CONF $APPS_DIR
    echo "Done: "$DEF_BACKUP_PATH"/"$FILE_PREFIX$TIME_STAMP".tar"
    cd "$PRE_CD"
    rm "$TMP_FILE"
elif [ "$1" == "-l" ];then       
    ls -l $DEF_BACKUP_PATH/$FILE_PREFIX*.tar | sed 's/\t/ /g' | sed 's/[ ][ ][ ]*/ /g' | cut -d' ' -f7 | sed "s/^/\/sdcard\//g"
else
    echo "Useage: recback.sh <option> [file]"
    echo "          -b         backup user data"
    echo "          -r <file>  restore the specified backup file"
    echo "          -l         list the backup files in default path"
    echo "                     default backup path: /sdcard"
fi
rm -r "$TMP_DIR"