2011年7月20日星期三

Android Wifi

1 system diagram

       The above figure is got from the web thank to the author J

The above figure is based on android 2.2 or anroid2.3, the latest version introduce WifiStateMachine class to track wifi state.

wpa_supplicant is in external directory, wifi is in hardware/libhardware_legacy/wifi

OK, let us focus on interfaces between different module.
There exists four type interfaces in android wifi system:
1) AIDL interface between WifiManager and WifiService
2) JNI interface between WifiNative and Wifi
3) Domain Socket interface between wpa_client used by Wifi and wpa_supplilcant
4) ioctrl interface between wpa_supplicant and wifi driver


2 AIDL interface between WifiManager and WifiService


this is aidl interface between different process. the interface is defined in IWifiManager:
interface IWifiManager
{
boolean enableNetwork(int netId, boolean disableOthers);
boolean startScan(boolean forceActive);
boolean setWifiEnabled(boolean enable);
boolean setWifiApEnabled(in WifiConfiguration wifiConfig, boolean enable);



}

setWifiEnabled function will enable the wifi network, its invocation sequence is as the following:
the invocation flow is
WifiManager-(AIDL)->WifiService-(JNI)->WifiNative-(socket)->WPA_CTRL

setWifiApEnabled the invoke flow is as the following:


Netd::SoftapControoller will invoke ioctrl function on mSock, and transfer the necessary property : like passwd, channel ).
mSock is created in the following way:
mSock = socket(AF_INET, SOCK_DGRAM,0)

3 JNI interface between WifiNative and Wifi

public class WifiNative {
public native static boolean loadDriver();
public native static boolean unloadDriver();
public native static boolean startSupplicant();
public native static boolean connectToSupplicant();


}

listNetworksCommand invoke sequence

4 domain socket interface between wpa_client and wpa_supplicant


this interface is mainly defined in wpa_ctrl.h
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path);
void wpa_ctrl_close(struct wpa_ctrl *ctrl);
int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
char *reply, size_t *reply_len,
void (*msg_cb)(char *msg, size_t len));
int wpa_ctrl_attach(struct wpa_ctrl *ctrl);
int wpa_ctrl_detach(struct wpa_ctrl *ctrl);
int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len);
int wpa_ctrl_pending(struct wpa_ctrl *ctrl);
int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl);
void wpa_ctrl_cleanup(void);


these interface use domain socket to communicate.

5  some tips when integrate wifi on android


start parameter of wpa_supplicant
wpa_supplicant -Dwext -imlan0 -c/data/misc/wifi/wpa_supplicant.conf
1)driver with wifi module is wext
2)ifname is mlan0
3)confname is /data/misc/wifi/wpa_supplicant.conf,


wpa_supplicant config file:
##### wpa_supplicant configuration file #####
update_config=1
ctrl_interface=/data/system/wpa_supplicant
eapol_version=1
ap_scan=1
fast_reauth=1

here, control unix domain socket of wpa_supplicant is at /data/system/wpa_supplicant/mlan0

Android Graphics 2

1 Surface Structure


This figure is based on froyo, and does not give detail about synchronization between Client and Server.
ISurface provide RPC interface between Client and Server.
GraphicBuffer encapsulate the memory shared by Client and Server
Surface in Client part transform the request for the upper framework and application to the Server Part Object SurfaceLayer.
SurfaceLayer in Server part will actually handle the request.

For ISurface,
It provide two group interface, one for SurfaceLayer, the other is used for SurfaceLayerBuffer.
SurfaceLayer means the memory for Surface is allocated in Server part, While SurfaceLayerBuffer means memory for Surface is transferred from the client.

For Surface:
For Surface, there exists two GraphicBuffer object, backBuffer for drawing and frontBuffer for displaying. The following invocation sequence display the first time to invoke Surface.lock function to get the addr of graphics memory

2 Surface Flinger
the main work of SurfaceFlinger is compose dirtry region of all layer to the backBuffer of current framebuffer, and then flip this backBuffer to display.

(I got this image from the web, thanks to the writer :) ) 


The following invocation sequence give more detail.


handlePageFlip;
In this function, SurfaceFlinger will invoke lockPageFlip of every Layer.
lockPageFlip is a very import function for Layer, it will create texture object used by Opengl library to do the composition, more details will be discripted in other document

if any layer need recomputeVisibleRegions, computeVisibleRegions will be invoked to re-compute every layer’s visible region on the framebuffer. this is a complex algorithm

ComposeSurface
general it will invoke draw function of every layer with the its visible region as parameter in Z-order

postFramebuffer
invoke eglSwapBuffers to display the final framebuffer

3 Gralloc&CopyBit
gralloc encapsulate the memory and framebuffer operation

GraphicsBuffer, GraphicsBufferMapper and GraphicBufferAllocator encapsulate memory operation of gralloc module.

These three class will help system to allocate graphics memory and map the shared graphics memory to the App process space. 

For framebuffer operation, it is related to FramebufferNativeWindow and DisplayHardware

copyBits module has be removed from 2.3 or 3.0 version,

and it mainly defined the following interface
int blit_copybit(
struct copybit_device_t *dev,
struct copybit_image_t const *dst,
struct copybit_image_t const *src,
struct copybit_region_t const *region)

int stretch_copybit(
struct copybit_device_t *dev,
struct copybit_image_t const *dst,
struct copybit_image_t const *src,
struct copybit_rect_t const *dst_rect,
struct copybit_rect_t const *src_rect,
struct copybit_region_t const *region) 

copyBits module is mainly used in andord software EGL/Opengl ES impl,

blit_copybit is mainly used in software EGL/Opengl ES eglSwapBuffers impl to copy minimum unchanged range from front buffer to back buffer. and blit_copybit does not take alpha into consideration .

stretch_copybit is mainly used software EGL/Opengl ES impl to draw Texture on the draw surface, It need take alpha value into consideration.


2011年7月19日星期二

Android Graphics 1

1 C/S aspect of Android Graphics



Android Graphics use a C/S structure.
Client part: for every activity in App, it is a client of android graphics. First time it need to do graphics operation, it will request android graph to allocate memory for it.
Server part: the main module in Server side is SurfaceFlinger, it will invoke gralloc module to allocate memory for framebuffer or app surface.

Shared part: The shared part mainly include two objects. Surface refer to graphics memory shared by Client part and Server part, SharedClient represent the synchronization mechanism between Client and Server part.

EGL/OPEGLES is the base for android graphics.

In Client part, App can determine whether use software (CPU) or hardware (GPU) to render app UI. If software render, skia libraries will be used, otherwise hwui libraries will be used instead.

Android provide a egl/opengl wrapper, any egl/opengl invocation will be dispatched in this wrapper to software egl/opengl or hardware egl/opengl according system configuration.



2 invoke sequence aspect of Android Graphics


Normal App and Java 3D Game App will invoke framework layer for various graphics operation. for normal app, all graphics operation is done by Skia libraries, for Java 3D app, all graphics operation will be done by opengl es libraries.
native 3D app will directly invoke opengle libraries through JNI or NDK.


3 android load opengl libraries


when android egl wrapper init, it will access confutation file “/system/lib/egl/egl.cfg” Every line in this file represent a kind of egl/opengles impl if, no this file, the system will use default android software egl/opengl impl.

the format of this file is
DISPLAY_ID IMPL_TYPE IMPL_TAG

DISPLAY_ID: default 0,
IMPL_TYPE: 0 means software impl
IMPL_TAG:the impl name, use this tag to load the correct library of this impl

for example
0 0 android
0 1 mali


4 Synchronization between Client and Server


The main data structure used in synchronization between Client and Server is SharedBufferStack, this structure is allocated in share memory(ashmem_create_region), can access in both Client and Server.

More description for DequeueCondition and RetireUpdate

DequeueCondition, RetireUpdate and other Condition and Update object is defined in frameworks\base\libs\surfaceflinger_client\SharedBufferStack.cpp

in DequeueCondition, it will check SharedBufferStack.available, when it is not larger than 0, the following logic will wait at a condition(SharedClient.cv)

In RetireUpdate,it will release the frontbuffer of the surface and increase SharedBufferStack.available, and then notify a condition(SharedClient.cv)


Here exists a important object-SharedClient.
Its definition as the following, and it has some tips for it


1) SharedClient is created share share memory(ashmem), This make sure SharedClient can be used across the processes.

2) The lock and cv member of SharedClient is mutex and condition, and at the same time they can also be accessed across the processes( through pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); and pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);)

3) For every Client, it will share a entry in surfaces member of SharedClient object, Client and server will use the content in this entry to make use synchronization of back and front buffer for Surface.

2011年7月18日星期一

Run Quake on Android


These days, do some optimization about android graphics, including EGL and opengl es. Find android external directory has a quake sub-directory. 

Read the Readme in this directory,
follow the steps identified in this readme.

first run, there 3 lines displayed on the screen:
"Missing data files. Looking for one of:
/sdcard/data/quake/id1/pak0.pak
/data/quake/id1/pak0.pak
Please copy a pak file to the device and reboot."

find external/quake -name pak0.pak  but nothing.

search in the google, :) find the website
http://quake.pocketmatrix.com/mods.php

download it pak0.pak.gz

put it into /sdcard/data/quake/id1/pak0.pak

re run it



In this case, logcat display Video mode is 1844x1038 and basically it is smooth.