tag:blogger.com,1999:blog-43395447537069436012024-03-13T09:34:53.933-07:00Let's talk about Google AndroidGoogle Android的那些事儿rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.comBlogger53125tag:blogger.com,1999:blog-4339544753706943601.post-69168260787367437072017-10-27T20:55:00.001-07:002017-10-27T20:55:31.137-07:00Build OpenCV for Android with LLVM C++ Runtime<div dir="ltr" style="text-align: left;" trbidi="on">
According to the <a href="https://developer.android.com/ndk/guides/cpp-support.html" target="_blank">Android NDK C++ Library Support</a>, LLVM's libc++ will be the only STL:<br /><blockquote>
<a href="https://libcxx.llvm.org/" target="_blank">LLVM's libc++</a> is the C++ standard library that has been used by the Android OS since Lollipop, and in the <a href="https://android.googlesource.com/platform/ndk/+/master/docs/Roadmap.md" target="_blank">future</a> will be the only STL available in the NDK.Until NDK r16, the NDK's libc++ is only of beta quality. Beginning with NDK r16, libc++ will be the preferred STL. A <a href="https://android.googlesource.com/platform/ndk/+/master/docs/Roadmap.md" target="_blank">future</a> NDK release will remove the other options.</blockquote>
<div>
If you are working with libraries linked with gnustl, you may have big problems.</div>
<div>
In this post, I introduce how I compile the OpenCV for Android with LLVM libc++ runtime.</div>
<h2 style="text-align: left;">
Install the cmake and cmake-gui</h2>
<div>
1. Dont install by sudo apt-get install (or update) cmake. Depends on the different Ubuntu version, you may not get the latest cmake installed.</div>
<div>
2. Uninstall the existing cmake: sudo apt-get purge cmake</div>
<div>
3. Download pre-compiled cmake package: <a href="https://cmake.org/download/" target="_blank">Latest Release (3.9.4)</a></div>
<div>
4. Install the cmake (cmake-gui is also included)</div>
<h2 style="text-align: left;">
Download the OpenCV source</h2>
<div>
OpenCV is available from github.</div>
<blockquote class="tr_bq">
git clone https://github.com/opencv/opencv.git<br />git clone https://github.com/opencv/opencv_contrib.git (Optional)</blockquote>
<h2 style="text-align: left;">
Cmake configuration</h2>
<div>
1. Start cmake-gui</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOGEOgDRxA1j29gfspuX0Ur8xLUuM2BwQF0f_uGXyiEuP2E4vPcA7rMFs5YtfrAtlicc9vlHAUSj_m-O-DF6mrV8OAEf1Tq4V6nHL8Dor8kSVnJBY6xaCXUI-eZlG0aKcCNJhVTUNKPG8/s1600/cmake-gui-snapshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="639" data-original-width="876" height="233" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOGEOgDRxA1j29gfspuX0Ur8xLUuM2BwQF0f_uGXyiEuP2E4vPcA7rMFs5YtfrAtlicc9vlHAUSj_m-O-DF6mrV8OAEf1Tq4V6nHL8Dor8kSVnJBY6xaCXUI-eZlG0aKcCNJhVTUNKPG8/s320/cmake-gui-snapshot.png" width="320" /></a></div>
<div>
2. Click the "Browse Source" button and give the OpenCV source folder</div>
<div>
3. Click the "Browse Build" button and give the build folder (e.g. create a folder: opencv_android_build)</div>
<div>
4. Click "Configure" button, select "Specify toolchain file for cross-compiling", in the next prompt window, make sure to select the "android.toolchain.cmake" under HOME_NDK/build/cmake/. Make sure not to use the file under opencv folder!!!</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCTsA0o0cT3WEiUvxeKL8PxZq2irVuX5ucs8wUeh-F8GC62-dRZxO7h9XNDwv_qL9MZSGFPLGq2Uk6ahJRG80S1f9JyX0iKCE3mZuuU66oIRzbvptmLx5LdJY5pXOJpCw8fkp5cI91FXs/s1600/cmake-gui-setup-snapshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="387" data-original-width="501" height="247" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCTsA0o0cT3WEiUvxeKL8PxZq2irVuX5ucs8wUeh-F8GC62-dRZxO7h9XNDwv_qL9MZSGFPLGq2Uk6ahJRG80S1f9JyX0iKCE3mZuuU66oIRzbvptmLx5LdJY5pXOJpCw8fkp5cI91FXs/s320/cmake-gui-setup-snapshot.png" width="320" /></a></div>
<div>
5. Click "Add Entry" button, add ANDROID_PLATFORM as String with value android-21</div>
<div>
6. Click "Add Entry" button, add ANDROID_STL as String with value c++_static</div>
<div>
7. Change the existing item CMAKE_BUILD_TYPE to Release</div>
<div>
8. Change the existing item CMAKE_CXX_STANDARD_LIBRARIES to libc++_static.a from libgnustl_static.a (under HOME_NDK/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/)</div>
<div>
9. Click "Configure" button to configure again</div>
<div>
10. Click "Generate" button to generate configuration</div>
<div>
11. Go to the build folder (e.g. opencv_android_build), run make -j to make the targets</div>
<div>
12. Run make install, the final files will be found under install folder.</div>
<div>
<br /></div>
<div>
Good luck!</div>
<div>
<br /></div>
</div>
rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com2tag:blogger.com,1999:blog-4339544753706943601.post-79075927685775280212015-11-30T13:52:00.002-08:002015-11-30T14:11:39.973-08:00Android smart phone with longer battery life (2)<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
This time, let's start from the healthd battery health monitor service start entrance. It is the healthd.cpp file from <a href="https://github.com/android/platform_system_core/blob/master/healthd/healthd.cpp" target="_blank">https://github.com/android/platform_system_core/blob/master/healthd/healthd.cpp</a>, here is the code snippets of main(...):<br />
<pre style="background: rgb(253, 246, 227);"><span style="color: #586e75;"><span style="color: #a57800;">int</span> <span style="color: #536871;">main</span>(int argc, char **argv) {</span><span style="color: red;"><span style="color: #586e75;">
int ch;
int ret;
klog_set_level(KLOG_LEVEL); // </span><span style="color: red;">logging into kernel<span style="color: #586e75;">
healthd_mode_ops = &android_ops; // <span style="color: red; font-size: 14px; line-height: 19.6px; text-align: justify;">setup the callback</span></span><span style="color: red;"><span style="color: #586e75;">
if (!</span><span style="color: #536871;">strcmp</span><span style="color: #586e75;">(</span><span style="color: #536871;">basename</span><span style="color: #586e75;">(argv[0]), "charger")) {
healthd_mode_ops = &charger_ops; // </span><span style="color: #586e75;">setup the charger only callback</span><span style="color: red;"><span style="color: #586e75;">
} else {
while ((ch = getopt(argc, argv, "cr")) != -1) {
switch (ch) {
case 'c':
healthd_mode_ops = &charger_ops;
break;
case 'r':
healthd_mode_ops = &recovery_ops; // </span></span></span></span></span><span style="color: red; font-size: 14px; line-height: 19.6px; text-align: justify;">setup recovery mode callback</span><!-------></pre>
</div>
The global variable healthd_mode_ops is an instance of struct healthd_mode_ops. It is to register the callbacks of battery monitor initialization and operations of update. The service has three different callbacks for normal bootup, recovery mode, and charger only mode respectively.<br />
<pre style="background: #fdf6e3; color: #586e75;"><span style="color: #073642; font-weight: 700;">struct</span> healthd_mode_ops {
<span style="color: #268bd2;">void</span> (*init)(<span style="color: #073642; font-weight: 700;">struct</span> healthd_config *config);
<span style="color: #268bd2;">int</span> (*preparetowait)(void);
<span style="color: #268bd2;">void</span> (*heartbeat)(void);
<span style="color: #268bd2;">void</span> (*battery_update)(<span style="color: #073642; font-weight: 700;">struct</span> android::BatteryProperties *props);
};
</pre>
Here is the normal mode callbacks:<br />
<pre style="background: #fdf6e3; color: #586e75;"><span style="color: #073642; font-weight: 700;">static</span> <span style="color: #073642; font-weight: 700;">struct</span> healthd_mode_ops android_ops = {
<span style="color: #268bd2;">.init</span> = healthd_mode_android_init,
<span style="color: #268bd2;">.preparetowait</span> = healthd_mode_android_preparetowait,
<span style="color: #268bd2;">.heartbeat</span> = healthd_mode_nop_heartbeat,
<span style="color: #268bd2;">.battery_update</span> = healthd_mode_android_battery_update,
};
</pre>
The callback functions are implemented in file: <a href="https://github.com/android/platform_system_core/blob/2655256570b7c1c5af6d886735835eecb99f45f2/healthd/healthd_mode_android.cpp" target="_blank">https://github.com/android/platform_system_core/blob/2655256570b7c1c5af6d886735835eecb99f45f2/healthd/healthd_mode_android.cpp</a>. We will re-visit the file in details a little later.<br />
After the callback installation, healthd_init() and an endless loop healthd_mainloop() is followed.<br />
<pre style="background: #fdf6e3; color: #586e75;"> ret = healthd_init();
<span style="color: #859900;">if</span> (ret) {
KLOG_ERROR("Initialization failed, exiting\n");
exit(2);
}
<span style="color: #536871;">healthd_mainloop</span>();
</pre>
And here is the healthd_init(), which finishes the following:<br />
<ul>
<li>create an epoll instance, it is a very scalable I/O event notification mechanism which is in here to monitor the kernel uevent updates, binder object, wakeup alarm timer etc.</li>
<li>call the registered init callback of healthd_mode_ops. We will re-visit later.</li>
<li>healthd_board_init(...), which actually does nothing here.</li>
<li>setup a wakeup alarm timer, add the timer file descriptor to be monitored by the epoll object. By default the fast timer internal is set.</li>
<li>setup a uevent, and add the uevent file descriptor to be monitored by the epoll object. This is here to get the battery subsystem updates from kernel.</li>
<li>create the BatteryMonitor object, and get BatteryMonitor initialized. The BatteryMonitor initialization has been visited in <a href="http://discuz-android.blogspot.com/2015/11/android-smart-phone-with-longer-battery.html" target="_blank">part I</a>.</li>
</ul>
<pre style="background: #fdf6e3; color: #586e75;"><span style="color: #073642; font-weight: 700;">static</span> <span style="color: #a57800;">int</span> <span style="color: #536871;">healthd_init</span>() {
epollfd = epoll_create(MAX_EPOLL_EVENTS);
if (epollfd == -1) {
KLOG_ERROR(LOG_TAG,
"epoll_create failed; errno=%d\n",
errno);
return -1;
}
healthd_mode_ops-><span style="color: #536871;">init</span>(&healthd_config);
healthd_board_init(&healthd_config);
wakealarm_init();
uevent_init();
gBatteryMonitor = new BatteryMonitor();
gBatteryMonitor-><span style="color: #536871;">init</span>(&healthd_config);
</pre>
Then it is an endless loop healthd_mainloop(). That is how the battery health state is get monitored continuously and endlessly. It waits on the epoll object, once any event happens the event callback will be called, which could be one or several of the registered events.<br />
<pre style="background: #fdf6e3; color: #586e75;"><span style="color: #073642; font-weight: 700;">static</span> <span style="color: #a57800;">void</span> <span style="color: #536871;">healthd_mainloop</span>(void) {
while (1) {
struct epoll_event events[eventct];
int nevents;
int timeout = awake_poll_interval;
int mode_timeout;
mode_timeout = healthd_mode_ops-><span style="color: #536871;">preparetowait</span>();
if (timeout < 0 || (mode_timeout > 0 && mode_timeout < timeout))
timeout = mode_timeout;
nevents = epoll_wait(epollfd, events, eventct, timeout);
if (nevents == -1) {
if (errno == EINTR)
continue;
KLOG_ERROR(LOG_TAG, "healthd_mainloop: epoll_wait failed\n");
break;
}
for (int n = 0; n < nevents; ++n) {
if (events[n]<span style="color: #268bd2;">.data</span><span style="color: #268bd2;">.ptr</span>)
(*(<span style="color: #536871;">void</span> (*)(int))events[n]<span style="color: #268bd2;">.data</span><span style="color: #268bd2;">.ptr</span>)(events[n]<span style="color: #268bd2;">.events</span>);
}
if (!nevents)
periodic_chores();
healthd_mode_ops-><span style="color: #536871;">heartbeat</span>();
}</pre>
<h3>
More details about callbacks of healthd_mode_android.cpp</h3>
Let's look into more details about the callbacks of file: <a href="https://github.com/android/platform_system_core/blob/2655256570b7c1c5af6d886735835eecb99f45f2/healthd/healthd_mode_android.cpp" target="_blank">https://github.com/android/platform_system_core/blob/2655256570b7c1c5af6d886735835eecb99f45f2/healthd/healthd_mode_android.cpp</a>.<br />
void healthd_mode_android_init(struct healthd_config* /*config*/) is the initialize function, it creates a binder object, add the binder object into the epoll polling list and install the callback for the operation when the binder object is polled by the epoll.<br />
<pre style="background: #fdf6e3; color: #586e75;"><span style="color: #a57800;">void</span> <span style="color: #536871;">healthd_mode_android_init</span>(struct healthd_config* /*config*/) {
ProcessState::self()-><span style="color: #536871;">setThreadPoolMaxThreadCount</span>(0);
IPCThreadState::self()-><span style="color: #536871;">disableBackgroundScheduling</span>(true);
IPCThreadState::self()-><span style="color: #536871;">setupPolling</span>(&gBinderFd);
if (gBinderFd >= 0) {
if (<span style="color: #536871;">healthd_register_event</span>(gBinderFd, binder_event))
KLOG_ERROR(LOG_TAG,
"Register for binder events failed\n");
}
</pre>
The installed epoll event callback for the binder is to process the binder commands:<br />
<pre style="background: #fdf6e3; color: #586e75;"><span style="color: #073642; font-weight: 700;">static</span> <span style="color: #a57800;">void</span> <span style="color: #536871;">binder_event</span>(uint32_t /*epevents*/) {
IPCThreadState::self()-><span style="color: #536871;">handlePolledCommands</span>();
}
</pre>
Finally the initialize register self as a service called "<span style="background-color: white; color: #183691; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 12px; line-height: 16.7999992370605px; white-space: pre;">batteryproperties</span>" to the android service manager. The android Java space can listen to the service to get the battery health state updates. Use the command: service list, you shall see the service "<span style="background-color: white; color: #183691; font-family: "consolas" , "liberation mono" , "menlo" , "courier" , monospace; font-size: 12px; line-height: 16.7999992370605px; white-space: pre;">batteryproperties</span>" listed.<br />
<pre style="background: rgb(253, 246, 227);"><span style="color: #586e75;"> <span style="color: #268bd2;">gBatteryPropertiesRegistrar</span> = <span style="color: #859900;">new</span> BatteryPropertiesRegistrar();
<span style="color: #268bd2;">gBatteryPropertiesRegistrar</span>-><span style="color: #536871;">publish</span>();
}</span><span style="font-family: "times new roman";"><span style="white-space: normal;"></span></span></pre>
void healthd_mode_android_battery_update(...) is the update callback. It is to notify all the registered service clients when the battery health state gets updated. It is the service listener's implementation of how to handle the battery state updates.<br />
<pre style="background: #fdf6e3; color: #586e75;"><span style="color: #a57800;">void</span> <span style="color: #536871;">healthd_mode_android_battery_update</span>(
struct android::BatteryProperties *props) {
if (gBatteryPropertiesRegistrar != NULL)
gBatteryPropertiesRegistrar-><span style="color: #536871;">notifyListeners</span>(*props);
return;
}
</pre>
<h3>
Callbacks of other two epoll objects</h3>
The uevent callback receives the kernel uevent updates, then parse the power_supply events, and reads the sysfs power_supply updates.<br />
<pre style="background: rgb(253, 246, 227);"><span style="color: #586e75;"><span style="color: #073642; font-weight: 700;">static</span> <span style="color: #a57800;">void</span> <span style="color: #536871;">uevent_event</span>(uint32_t /*epevents*/) {
char msg[UEVENT_MSG_LEN+2];
char *cp;
int n;
n = uevent_kernel_multicast_recv(uevent_fd, msg, UEVENT_MSG_LEN);
if (n <= 0)
return;
if (n >= UEVENT_MSG_LEN) /* overflow -- discard */
return;
msg[n] = '\0';
msg[n+1] = '\0';
cp = msg;
while (*cp) {
if (!<span style="color: #536871;">strcmp</span>(cp, "SUBSYSTEM=" POWER_SUPPLY_SUBSYSTEM)) { // </span><span style="color: red;">power_supply only<span style="color: #586e75;">
healthd_battery_update(); // </span><span style="color: #586e75;">reads the power_supply sysfs into memory</span><span style="color: red;"><span style="color: #586e75;">
break;
}
/* advance to after the next \0 */
while (*cp++)
;
}
}
</span><!------></span><!------></span></pre>
The wakeup timer object setup the timer to wakeup from kernel sleep and gets the power_supply updates.<br />
<pre style="background: rgb(253, 246, 227);"><span style="color: #586e75;"><span style="color: #073642; font-weight: 700;">static</span> <span style="color: #a57800;">void</span> <span style="color: #536871;">wakealarm_event</span>(uint32_t /*epevents*/) {
... ...
periodic_chores();
}
<span style="color: #073642; font-weight: 700;">static</span> <span style="color: #a57800;">void</span> <span style="color: #536871;">periodic_chores</span>() {
healthd_battery_update(); </span><span style="color: red;">// reads the power_supply sysfs into memory<span style="color: #586e75;">
}
</span><!------></span></pre>
Will illustrate how to get the battery state updates from Java with an sample app in the next article.</div>
rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com1tag:blogger.com,1999:blog-4339544753706943601.post-49433153826187253842015-11-30T08:41:00.003-08:002015-11-30T13:58:39.834-08:00Android smart phone with longer battery life<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
Smart phones have been developed a lot with more cpu cores, more computation capabilities, with larger and brighter screens, with higher resolution cameras and etc. But battery is one of the areas have no breakthrough. Talking to the battery life, because of the faster cpu/gpu, bigger screen, it even gets worse. Do you still remember the last time you got so mad to find a power supply outlet?<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaLVO1PgUMWRfteGsr9t0AE2hyphenhyphenS5RfOo263SZV2_owgNNrkRM0GhY8bvHiVbciuJSknMaMIIq1aO7bHKaI1Qnqc1m7Xv2fthuKtwWCs96WcWtvH4ZdrURTraeA1cIhSun6L0oZOKtlyww/s1600/battery_life.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="197" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaLVO1PgUMWRfteGsr9t0AE2hyphenhyphenS5RfOo263SZV2_owgNNrkRM0GhY8bvHiVbciuJSknMaMIIq1aO7bHKaI1Qnqc1m7Xv2fthuKtwWCs96WcWtvH4ZdrURTraeA1cIhSun6L0oZOKtlyww/s200/battery_life.jpg" width="200" /></a>Smart phones use Li-ion batteries. Before Li-ion batteries improve the capacity with the technology breakthrough, how to save the battery life becomes very important as we dont have too much to waste. To save the battery life keeping closely monitoring the battery life is the first step.<br />
Start from Android KK (Kitkat) Android adds the system/core/healthd, which is built into part of Android system image as /sbin/healthd, to monitor the battery state. In this article let's take a close look into healthd to understand how can we monitor the battery state.<br />
<h3>
What does healthd monitor and tell?</h3>
First let's take a look at the healthd logs:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;"><14>[21867.192464] healthd: battery l=78 v=4024 t=18.8 h=2 st=4 c=-239 chg=a
<14>[21867.421852] healthd: battery l=78 v=4067 t=18.8 h=2 st=2 c=5 chg=a
<14>[21867.448320] healthd: battery l=78 v=4067 t=18.8 h=2 st=2 c=5 chg=a<!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--><!--14--></14></14></14></code></pre>
The healthd monitors the battery state of charge and reports 7 outputs. They are battery level (l=78), voltage (v=4024), battery temperature (t=18.8), health state (h=2), battery status (st=4), charging/discharging current (c=-239), and charging status/charger type (chg=a).<br />
<br />
<ul>
<li>Battery level: values in 0 ~ 100, means no battery to full battery.</li>
<li>Battery voltage: voltage in mV, lower battery level, less voltage.</li>
<li>Battery temperature: temperature in <span style="font-family: "georgia";">Celsius (°C).</span></li>
<li>Health state: values in 1 ~ 7. It is a enumeration with following health state:</li>
<ul>
<li>1 -> Unknown</li>
<li>2 -> Good</li>
<li>3 -> Overheat</li>
<li>4 -> Dead</li>
<li>5 -> Over voltage</li>
<li>6 -> Unspecified failure</li>
<li>7 -> Cold</li>
</ul>
<li>Battery status: values in 1 ~ 5. It is a enumeration with following battery status:</li>
<ul>
<li>1 -> Unknown</li>
<li>2 -> Charging</li>
<li>3 -> Discharging</li>
<li>4 -> Not charging</li>
<li>5 -> Full</li>
</ul>
<li>Charging/discharging current: positive value means discharging current in mV, negative value means charging current in mV.</li>
<li>Charging status: empty if not on charging. a/u/w otherwise:</li>
<ul>
<li>a: charger AC online</li>
<li>u: charger USB online</li>
<li>w: charger wireless online</li>
</ul>
</ul>
<h3>
How does healthd read the battery health data?</h3>
The battery driver exports the virtual sysfs under /sys/class/power_supply for upper layer to get the battery health data. Let's review the code <a href="https://github.com/android/platform_system_core/blob/master/healthd/BatteryMonitor.cpp" target="_blank">https://github.com/android/platform_system_core/blob/master/healthd/BatteryMonitor.cpp</a> to understand how healthd gets the battery health data.<br />
<br />
BatteryMonitor::init(...) function: open /sys/class/power_supply directory, read and traverse<br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">void BatteryMonitor::init(struct healthd_config *hc) {
String8 path;
char pval[PROPERTY_VALUE_MAX];
mHealthdConfig = hc;
DIR* dir = opendir(POWER_SUPPLY_SYSFS_PATH); </code><code style="color: black; word-wrap: normal;"><span style="color: red;">/* open folder /sys/class/power_supply */</span></code><code style="color: black; word-wrap: normal;">
if (dir == NULL) {
KLOG_ERROR(LOG_TAG, "Could not open %s\n", POWER_SUPPLY_SYSFS_PATH);
} else {
struct dirent* entry;
while ((entry = readdir(dir))) { </code><code style="color: black; word-wrap: normal;"><span style="color: red;">/* loop and read files in /sys/class/power_supply */</span></code><code style="color: black; word-wrap: normal;">
</code><!------></pre>
</div>
In sysfs folder /sys/class/power_supply, there is a list of power_supply supported by the given smart phone. In each power_supply folder, there are some attributes. One of the attributes every power_supply shall have is the type. Following code snippets check the type of each power_supply to determine the next things to check:<br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">394 // Look for "type" file in each subdirectory
395 path.clear();
396 path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH, name);
397 switch(readPowerSupplyType(path)) {
398 case ANDROID_POWER_SUPPLY_TYPE_AC:
399 case ANDROID_POWER_SUPPLY_TYPE_USB:
400 case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
... ...
407 case ANDROID_POWER_SUPPLY_TYPE_BATTERY:
... ...
506 case ANDROID_POWER_SUPPLY_TYPE_UNKNOWN:
... ...
</code></pre>
If power_supply type is other than Battery or Unknown, then power_supply type should be one of the following:<br />
<ul>
<li>ANDROID_POWER_SUPPLY_TYPE_AC</li>
<li>ANDROID_POWER_SUPPLY_TYPE_USB</li>
<li>ANDROID_POWER_SUPPLY_TYPE_WIRELESS</li>
</ul>
and /sys/class/power_supply/%power_supply_type%/online will be further checked to see if such power_supply is plugged to charge the given smart phone.<br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">401 path.clear();
402 path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH, name);
403 if (access(path.string(), R_OK) == 0)
404 mChargerNames.add(String8(name));
405 break;
... ...
215 for (i = 0; i < mChargerNames.size(); i++) {
216 String8 path;
217 path.appendFormat("%s/%s/online", POWER_SUPPLY_SYSFS_PATH,
218 mChargerNames[i].string());
219
220 if (readFromFile(path, buf, SIZE) > 0) { </code><code style="color: black; word-wrap: normal;"><span style="color: red;">/* online */</span></code><code style="color: black; word-wrap: normal;">
221 if (buf[0] != '0') {
222 path.clear();
223 path.appendFormat("%s/%s/type", POWER_SUPPLY_SYSFS_PATH,
224 mChargerNames[i].string());
225 switch(readPowerSupplyType(path)) {
226 case ANDROID_POWER_SUPPLY_TYPE_AC:
227 props.chargerAcOnline = true;
228 break;
229 case ANDROID_POWER_SUPPLY_TYPE_USB:
230 props.chargerUsbOnline = true;
231 break;
232 case ANDROID_POWER_SUPPLY_TYPE_WIRELESS:
233 props.chargerWirelessOnline = true;
234 break;
235 default:
236 KLOG_WARNING(LOG_TAG, "%s: Unknown power supply type\n",
237 mChargerNames[i].string());
238 }
239 }
240 }
241 }
</code></pre>
If power_supply is Battery, it checks more attributes under sysfs folder /sys/class/power_supply/battery, such as status, health, present, capacity, voltage_now/batt_vol, current_now, current_avg, charge_counter, temp/batt_temp, technology.<br />
Read battery level in percentages and battery voltage in mV:<br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">191 props.batteryLevel = mBatteryFixedCapacity ?
192 mBatteryFixedCapacity :
193 getIntField(mHealthdConfig->batteryCapacityPath);
194 props.batteryVoltage = getIntField(mHealthdConfig->batteryVoltagePath) / 1000;
</code></pre>
Read battery temperature in Celsius (°C):<br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">196 props.batteryTemperature = mBatteryFixedTemperature ?
197 mBatteryFixedTemperature :
198 getIntField(mHealthdConfig->batteryTemperaturePath);
</code></pre>
Read battery status:<br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">204 if (readFromFile(mHealthdConfig->batteryStatusPath, buf, SIZE) > 0)
205 props.batteryStatus = getBatteryStatus(buf);
57int BatteryMonitor::getBatteryStatus(const char* status) {
58 int ret;
59 struct sysfsStringEnumMap batteryStatusMap[] = {
60 { "Unknown", BATTERY_STATUS_UNKNOWN },
61 { "Charging", BATTERY_STATUS_CHARGING },
62 { "Discharging", BATTERY_STATUS_DISCHARGING },
63 { "Not charging", BATTERY_STATUS_NOT_CHARGING },
64 { "Full", BATTERY_STATUS_FULL },
65 { NULL, 0 },
66 };
67
68 ret = mapSysfsString(status, batteryStatusMap);
</code></pre>
Read battery health state:<br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">207 if (readFromFile(mHealthdConfig->batteryHealthPath, buf, SIZE) > 0)
208 props.batteryHealth = getBatteryHealth(buf);
77int BatteryMonitor::getBatteryHealth(const char* status) {
78 int ret;
79 struct sysfsStringEnumMap batteryHealthMap[] = {
80 { "Unknown", BATTERY_HEALTH_UNKNOWN },
81 { "Good", BATTERY_HEALTH_GOOD },
82 { "Overheat", BATTERY_HEALTH_OVERHEAT },
83 { "Dead", BATTERY_HEALTH_DEAD },
84 { "Over voltage", BATTERY_HEALTH_OVER_VOLTAGE },
85 { "Unspecified failure", BATTERY_HEALTH_UNSPECIFIED_FAILURE },
86 { "Cold", BATTERY_HEALTH_COLD },
87 { NULL, 0 },
88 };
89
90 ret = mapSysfsString(status, batteryHealthMap);
</code></pre>
After BatteryMonitor.cpp traverse the sysfs folder /sys/class/power_supply and update the attributes, the following code snippets is to notify the applications who concern the battery health state.<br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code style="color: black; word-wrap: normal;">275 healthd_mode_ops->battery_update(&props);
</code></pre>
It is a callback function registered at the beginning of the health monitoring service. Have to cut here. Will continue with a new article.</div>
rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com0tag:blogger.com,1999:blog-4339544753706943601.post-50186462845932945362012-03-28T20:01:00.004-07:002012-03-28T20:39:49.395-07:00memory leak tracking on android, contYou have Android version >= 2.2.<div>Make sure you have libc_malloc_debug_leak.so:</div><div><ul><li><span style="font-size: 100%; ">> adb shell ls /system/lib/libc_malloc_debug_leak.so</span></li></ul></div><div><span style="font-size: 100%; ">Enable the memory leak check:</span></div><div><ul><li><span style="font-size: 100%; ">> adb shell setprop libc.debug.malloc 1</span></li></ul></div><div>Restart the Android framework, make sure the memory leak check is functional:</div><div><ul><li><span style="font-size: 100%; ">> adb shell stop</span></li><li><span style="font-size: 100%; ">> adb shell start</span></li><li><span style="font-size: 100%; ">> adb logcat -b main -v threadtime (you see this line in the printed log: </span><span style="font-size: 100%; ">03-29 03:10:52.942 4200 4200 I libc : /system/bin/logcat using MALLOC_DEBUG = 1 (leak checker)</span><span style="font-size: 100%; ">)</span></li></ul></div><div>In your DDMS configuration file (e.g. ~/.android/ddms.cfg on Linux), add "native=true". This enables the Native Heap tab. Now you can use the "Native Heap" tab features to grab snapshots of the heap memory usage. Group by library to view the memory usage in libraries. Show new allocations comparing to the previous snapshot to monitor the memory allocation increments. If you are using the images built by your own, fill the "Symbol Search Path" to get more details information.</div><div><br /></div><div><span style="font-size: 100%; ">More options:</span></div><div><ul><li><span style="font-size: 100%; ">> adb shell setprop libc.debug.malloc 5</span></li></ul></div><div></div><blockquote><div># For filling allocated /freed memory with patterns defined by CHK_SENTINEL_VALUE, and CHK_FILL_FREE macros.</div></blockquote><div><ul><li><span style="font-size: 100%; ">> adb shell setprop libc.debug.malloc 10</span></li></ul></div><div><blockquote># For adding pre-, and post- allocation stubs in order to detect buffer overruns.</blockquote></div>rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com6tag:blogger.com,1999:blog-4339544753706943601.post-54546023022775636162011-09-26T01:17:00.000-07:002011-09-26T01:17:57.364-07:00Android sh script, why failed with [ not foundA simple sh script, but run failure with error: [ not found.<br />
<blockquote>
#!/system/bin/sh<br />
if [ $? eq 0 ]; then<br />
echo "Command run successful"<br />
fi</blockquote>
The same script can run well on Linux.<br />
I dont know why, but I finally got a solution.<br />
Upload a busybox, change it to executable permissions, create a soft link "[" to busybox. Like the following:<br />
<blockquote>
-rwxr-xr-x 500 500 1877260 2011-09-22 02:42 busybox<br />
lrwxrwxrwx root root 2011-09-26 08:15 [ -> /sbin/busybox</blockquote>
Run the sh script again, which shall give no error any more.<br />
Finally, make sure the searching path $PATH can find command "busybox", and "[".rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com19tag:blogger.com,1999:blog-4339544753706943601.post-54624978204348404202011-07-14T02:55:00.001-07:002011-07-14T02:59:07.515-07:00Disable Linux kernel version magic checkLinux kernel will refuse to load kernel module if the version magic is not match. It can be easily disabled for some ease.<br />Find linux kernel kernel/module.c, find "check_modinfo" function, comment out "return -ENOEXEC;" for same_magic(...) check function.rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com8tag:blogger.com,1999:blog-4339544753706943601.post-91071813024942975692011-07-14T02:45:00.000-07:002011-07-14T02:54:26.592-07:00How to get a console with root if Motorola XOOM is working as USB Host and connected with USB devicesIf Motorola XOOM is connected with USB devices and working as USB Host mode, you will not be able to have adb shell work on PC. The only USB connection is used for other purpose. Here is a tip to have a console with root even the USB connection is used for USB device.<br /><ul><li>Motorola XOOM is rooted</li><li>Push a busybox to Motorola XOOM, make it executable</li><li>Connect Motorola XOOM with PC, in a PC cmd window, adb shell to the device, the shell must be a root shell.</li><li>Start telnetd: busybox telnetd -l /system/bin/sh</li><li>Download a telnet APP for Motorola XOOM, e.g. BlowTorch. Launch telnet client (BlowTorch), telnet to device, a root console is served.</li></ul>rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com4tag:blogger.com,1999:blog-4339544753706943601.post-610632647975264522011-07-13T06:00:00.000-07:002011-07-13T06:34:48.960-07:00USB Host Mode on Motorola XOOMMotorola XOOM gets USB host functionality. No software changes, this article shows you how to enable Motorola XOOM the ability of USB host functionality, which grant you the potential to have the ability to read media from external SD card reader, USB HD, USB DVD adapter, USB LAN adapter, and etc. Potentially, Motorola XOOM can work as a PC and access all kinds of external USB devices. Will introduce the software level changes later to enable reading from SD card reader, connect USB LAN, etc.<br />Motorola XOOM works as a portable device (just like the mobile phone), provides a micro-usb to connect to PC. In this way, PC can access media in the Motorola XOOM. Motorola XOOM works as a USB client.<br />Motorola XOOM can also work in Host mode, because it has the USB OTG (on-the-go). How to switch the USB OTG on the Motorola XOOM to USB Host mode? It is very simple. You just need need a USB toggle cable. The USB toggle cable looks like the following:<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA1-V59akpCqTBmmvlF3oq-gpgGBHY6Z9GqPEx6-UIEJOd_df0eYvjMlgWD1U7YtYcQtoLaq_dsN8_bA736Dq_7-g_Ju_MocXBjz1sgwDiJC7Z1T6DdUcZ67YKdWCMZNpKSLUb5hr5oQo/s1600/toggle.png"><img style="margin: 0pt 10px 10px 0pt; display: block; text-align: center; cursor: pointer; width: 400px; height: 103px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA1-V59akpCqTBmmvlF3oq-gpgGBHY6Z9GqPEx6-UIEJOd_df0eYvjMlgWD1U7YtYcQtoLaq_dsN8_bA736Dq_7-g_Ju_MocXBjz1sgwDiJC7Z1T6DdUcZ67YKdWCMZNpKSLUb5hr5oQo/s400/toggle.png" alt="" id="BLOGGER_PHOTO_ID_5628824982281794882" border="0" /></a><br />After the Motorola XOOM plugs with this USB toggle cable, it can connect with all kinds of USB devices. To make the USB devices work on Motorola XOOM, linux drivers change may be needed. Will introduce some later.<br />In the kernel log, following message will be shown after USB toggle cable connected:<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4j8tuifIvtkTpCuELt-T_nrB_WyFvXQb1gJk30R1JgXDpqsEpa_2N_QnNlAXMbntT14vRbomxIn74KpfXImJBE9vZqMhLUVxR5ZaAOckY_r2yldhGA1nWtl1EeBYRaIu9vg9ApwwDqOI/s1600/dmesg_otg.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 100px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4j8tuifIvtkTpCuELt-T_nrB_WyFvXQb1gJk30R1JgXDpqsEpa_2N_QnNlAXMbntT14vRbomxIn74KpfXImJBE9vZqMhLUVxR5ZaAOckY_r2yldhGA1nWtl1EeBYRaIu9vg9ApwwDqOI/s400/dmesg_otg.jpg" alt="" id="BLOGGER_PHOTO_ID_5628829276229283490" border="0" /></a>rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com2tag:blogger.com,1999:blog-4339544753706943601.post-58430289818265441012011-07-12T22:54:00.000-07:002011-07-14T03:07:12.787-07:00Step by step to enable LAN access for Motorola XOOMWith the USB toggle cable connected with Motorola XOOM, Motorola XOOM can work with all kinds of USB devices, such as USB LAN, so to connect with Local Area Network.<br />Pre-requisite:<br /><ul><li>A rooted Motorola XOOM</li><li>USB toggle cable</li><li>USB LAN adapter</li><li>Networking Cat5 cable</li></ul>USB LAN adapter:<blockquote>Google USB LAN adapter, there are many USB LAN adapter. A typical USB LAN adapter is shown below.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFlglvHsarMQjSmCOWzp8gGff0pWhT2JOqyLUAZU29smtOnLg3BfIkXE_wv-U-2cqNtbJGitMNG8XVKHCSvPmZYyvzHT-wcgUKxC7VVl7eV1poUtV666oND5nW4rDF632UptWOdeLE3mM/s1600/usblan.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 168px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFlglvHsarMQjSmCOWzp8gGff0pWhT2JOqyLUAZU29smtOnLg3BfIkXE_wv-U-2cqNtbJGitMNG8XVKHCSvPmZYyvzHT-wcgUKxC7VVl7eV1poUtV666oND5nW4rDF632UptWOdeLE3mM/s400/usblan.png" alt="" id="BLOGGER_PHOTO_ID_5629131886441713586" border="0" /></a></blockquote>Networking Cat5 cable:<br /><blockquote>Not sure why, but looks a straight through Networking Cat5 cable does not work with the above USB LAN adapter. Make sure the cable has one end terminated with T568A scheme, the other end terminated with T568B scheme. Google them for more details.</blockquote>Kernel driver changes:<br /><ul><li>Get to know the USB LAN adapter device ID and vendor ID. With USB LAN adapter connected with Motorola XOOM through USB toggle cable, find dmesg kernel log with following information. Write down the device ID and vendor ID.<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNklyAjRnEc8NIcXGSs9YbiEgWobxMmvWyUTPBIbGdRvFsOWV4hYmv2yowdZC5MAqEfSLL7GR4tqMBV-JKbRJswCzb2qVXHtfG7m0Tmi5bgh3PIdnwFo6WB2zQzvdjF_YNO8FvA-jgOJQ/s1600/dmesg.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 139px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNklyAjRnEc8NIcXGSs9YbiEgWobxMmvWyUTPBIbGdRvFsOWV4hYmv2yowdZC5MAqEfSLL7GR4tqMBV-JKbRJswCzb2qVXHtfG7m0Tmi5bgh3PIdnwFo6WB2zQzvdjF_YNO8FvA-jgOJQ/s400/dmesg.jpg" alt="" id="BLOGGER_PHOTO_ID_5629147196522015442" border="0" /></a></li><li>Add "CONFIG_USB_NET_DM9601=y" into kernel config file to have drivers/net/usb/dm9601.c compiled into kernel object.</li><li>Add vendor ID and device ID into drivers/net/usb/dm9601.c, struct usb_device_id structure, referenced by variable products[]. e.g.</li><blockquote><li>+ {</li><li>+ USB_DEVICE(0x0fe6, 0x9700), /* XXXY */</li><li>+ .driver_info = (unsigned long)&dm9601_info,</li><li>+ },</li></blockquote><li>Compile the kernel, and apply new kernel to Motorola XOOM. New kernel will fail to load Wifi module because of un-matched kernel version magic, disable kernel version magic matching will resolve this issue.</li></ul>DHCP client for USB LAN adapter interface:<br /><blockquote>Power up Motorola XOOM with Network Cat5 cable connected with Motorola XOOM through USB LAN adapter and USB toggle cable. The connection looks like the following. After XOOM is up, run "dhcpcd eth0" in a console with root. After dhcpcd return, eth0 shall get an IP. Ping command shall work. But browser still not work.<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisMueBKT4hieh_Tgh0verf-kgeheGwI-sl0sajr0ihWR27XSqVZhYVYKk9F4wX07RhKmR5MEIzwjfZCXYQKQmAbSjeqZVfUYY2PJIydtcdrT4JniiyhC-L82kBQryAUqYyD2X6PElyHtY/s1600/usblan_conn.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 160px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisMueBKT4hieh_Tgh0verf-kgeheGwI-sl0sajr0ihWR27XSqVZhYVYKk9F4wX07RhKmR5MEIzwjfZCXYQKQmAbSjeqZVfUYY2PJIydtcdrT4JniiyhC-L82kBQryAUqYyD2X6PElyHtY/s400/usblan_conn.png" alt="" id="BLOGGER_PHOTO_ID_5629139493783691906" border="0" /></a></blockquote>Make XOOM browser work in LAN:<br /><blockquote>In a console with root, run following commands:<br /><ul><li>getprop dhcp.eth0.dns1 # get dns1</li><li>getprop dhcp.eth0.dns2 # get dns2</li><li>setprop net.dns1 dns1</li><li>setprop net.dns2 dns2</li><li>Browser shall work now</li></ul></blockquote>How to have USB LAN work automatically:<br /><blockquote>Write a NETLINK socket program to listen all NETLINK socket event, if eth0 interface is UP, run dhcpcd on eth0 and set net.dns1, net.dns2 with dhcp.eth0.dns1 and dhcp.eth0.dns2. If eth0 interface is DOWN, reset those properties.</blockquote>rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com7tag:blogger.com,1999:blog-4339544753706943601.post-49923982259389959902010-08-27T01:22:00.000-07:002010-08-27T01:48:51.267-07:00patch the kernel image boot.imgTools list:<br /><ol><li><a href="http://android-dls.com/files/linux/split_bootimg.zip">split_bootimg.pl</a></li><li><a href="http://git.source.android.com/?p=platform/system/core.git;a=tree;f=mkbootimg">mkbootimg</a></li><li>mkbootfs</li></ol>boot.img contains the linux kernel and the ramdisk, while the default.prop in ramdisk can enable/disable the adb root permission. following is the default.prop contents for a droid product device:<br /><ul><li>ro.secure=1 </li><li>ro.allow.mock.location=0</li><li>ro.debuggable=0 </li><li>persist.service.adb.enable=0</li></ul>droid product device with above default.prop has no adb root permissions if the device is not hacked. the default.prop with the following contents has the adb root permissions by default:<br /><ul><li>ro.secure=0</li><li>ro.allow.mock.location=0</li><li>ro.debuggable=1</li><li>persist.service.adb.enable=1</li></ul>to create a boot.img with such default.prop, here is the steps:<br /><ol><li>split the boot.img: split_bootimg.pl boot.img, after running the command, two files are generated: boot.img-kernel and boot.img-ramdisk.gz.</li><li>create a temp folder (e.g. ramdisk), change to that folder, run the following command to extract the boot.img-ramdisk.gz: cat ../boot.img-ramdisk.gz | gzip -d | cpio -idm.</li><li>make the changes to the ramdisk file system in ramdisk folder, e.g. change the default.prop file to get adb root permissions.</li><li>return the parent folder, and run the following command to recreate the ramdisk package: mkbootfs ./ramdisk | gzip > ramdisk-new.gz</li><li>recreate the boot image: mkbootimg --kernel boot.img-kernel --ramdisk ramdisk-new.gz -o boot-new.img</li></ol>done. flash the boot-new.img to the device with fastboot.<br />more things can be done with the above steps, such as change the boot up sequence by modify the init.rc.rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com7tag:blogger.com,1999:blog-4339544753706943601.post-91369819836290300332010-08-24T18:38:00.000-07:002010-08-24T18:46:51.236-07:00unyaffs the android image<a href="http://code.google.com/p/unyaffs/">unyaffs </a>is a tool to extract files from a yaffs file system image. It supports extract images created by mkyaffs2image. It is useful to patch the system.img and re-generate the system.img.<br />How to get it:<br /><ol><li>download a pre-build binary for linux: http://unyaffs.googlecode.com/files/unyaffs</li><li>download the source and compile with gcc -o unyaffs unyaffs.c:</li></ol><ul><li>http://unyaffs.googlecode.com/files/unyaffs.c</li><li>http://unyaffs.googlecode.com/files/unyaffs.h</li></ul>rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com3tag:blogger.com,1999:blog-4339544753706943601.post-63652665933017148892009-09-24T01:34:00.001-07:002009-09-24T01:35:02.979-07:00E-book: The Busy Coder's Guide to Android Development<the>, NOT BAD. Google it to find details.rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com13tag:blogger.com,1999:blog-4339544753706943601.post-4538812081900376392009-08-06T19:29:00.000-07:002009-08-06T19:45:13.679-07:00Automatic Memory Leak Tracking on AndroidAndroid provides a mechanism to track memory leakage.<br />In folder bionic/libc/bionic/malloc_leak.c is compiled into /system/lib/libc_debug.so, it is a memory leakage tracking version of libc.so. To enable the memory leakage tracking, replace the /system/lib/libc.so with the /system/lib/libc_debug.so.<br /><blockquote>> adb shell mv /system/lib/libc.so /system/lib/libc_original.so<br />> adb shell mv /system/lib/libc_debug.so /system/lib/libc.so </blockquote>Before doing that, be sure to remount the system partition to 'rw'.<br />Use 'mv' command may have problem without libc.so, in that case use 'cp' command instead.<br />With the memory leak tracking, you shall see something like "MALLOC_DEBUG = 1 (leak checker)" in your logcat output.rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com10tag:blogger.com,1999:blog-4339544753706943601.post-43305980964997578272009-06-11T23:48:00.000-07:002009-06-12T00:14:44.530-07:00android memory usage with hprofAndroid provides some mechanisms to generate hprof data:<br /><ol><li>Dalvik VM will dump hprof file within /data/misc folder if SIGUSR1 and/or SIGQUIT signal is received. Manually send SIGUSR1 to process: kill -10 pid.</li><li>The android provides monkey tool (random testing tool), with --hprof option will generate hprof file within /data/misc folder.</li><li>In cupcake release, a new API has been introduced to generate a dump programmatically, the static method dumpHprofData(String fileName) of the Debug class. Example: Debug.dumpHprofData("xxx.hprof").</li></ol>Some tips:<br /><ol><li>The folder /data/misc shall have 777 permissions.</li><li>The hprof file format is heap-dump-tm<timestamp>-pid<pid>.hprof-head and heap-dump-tm<timestamp>-pid<pid>.hprof if android 1.1 release is used.</li><li>The hprof file format is heap-dump-tm<timestamp>-pid<pid>.hprof if android 1.5 release is used.</li><li>If two files are generated, you need to join the two files into one: type heap-dump-tm<timestamp>-pid<pid>.hprof-head > dump.hprof; type heap-dump-tm<timestamp>-pid<pid>.hprof >> dump.hprof.</li><li>Convert the hprof to standard hprof format: hprofconv dump.hprof out_dump.hprof</li><li>Use JProfiler, Eclipse MAT, or other tools to open out_dump.hprof. I tried JProfiler and got the same problems as indicated in <a href="http://osdir.com/ml/android-porting/2009-04/msg00597.html">http://osdir.com/ml/android-porting/2009-04/msg00597.html</a>.</li></ol>Some resources:<br /><ol><li>Eclipse MAT: http://www.eclipse.org/mat/</li><li>MAT standalone: <a href="http://mirror.cc.columbia.edu/pub/software/eclipse/technology/mat/0.7/rcp/MemoryAnalyzer-Incubation-0.7.0.20081210-win32.win32.x86.zip">MemoryAnalyzer-Incubation-0.7.0.20081210-win32.win32.x86.zip</a></li><li>Hprofconv: http://bigflake.com/HprofConv.c.txt</li></ol>rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com20tag:blogger.com,1999:blog-4339544753706943601.post-91809828881051806392009-06-08T20:01:00.000-07:002009-06-08T20:08:34.956-07:00Android Java Space OOMThe default Android java space heap maximum limitation is 16M. If you are running multimedia applications on android, such as jpg file decoding, video decoding, you may run OOM (Out Of Memory). If memory tuning can not help you on the OOM, you can go to the file: frameworks/base/core/jni/AndroidRuntime.cpp, line 607, change opt.optionString = "-Xmx16m" to opt.optionString = "-Xmx20m" for 20M heap size or even bigger.<br />The limitation is the upward limitation, it will not actually allocate 20M memory every time in every java application.<br />Take this solution as the last try, focus on your coding quality first.rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com4tag:blogger.com,1999:blog-4339544753706943601.post-15887227332510234362009-06-08T19:53:00.001-07:002009-06-08T20:01:05.445-07:00Tools to monitor your android system memory and performanceTools to monitor your android/linux system memory and performance:<br /><ul><li>ps -x</li><li>top</li><li>cat /proc/meminfo</li><li>dumpsys meminfo proc-id</li><li>procrank</li><li>DDMS (Android SDK tool)</li><li>time command-line</li><li>vmstat</li></ul>rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com4tag:blogger.com,1999:blog-4339544753706943601.post-82339845127234614252009-06-08T19:41:00.000-07:002009-06-08T19:50:30.216-07:00Android java space profiling tool - traceviewAndroid provides a good java space profiling tool: traceview. Traceview can be found in the same folder as adb in Android SDK package. Usage is quite simple and straightforward:<br /><ol><li>import android.os.Debug;</li><li>Debug.startMethodTracing("tag-name");<br /></li><li>Debug.stopMethodTracing();</li><li>Run the Java application</li><li>Fetch out the profiling output file on SD card (SD card is needed) root folder: tag-name.trace</li><li>traceview tag-name.trace to open the traceview window</li></ol>Insert items 1, 2, 3 into your java source code where you want to do profiling.<br />For more information about traceview window, refer to http://developer.android.com/guide/developing/tools/traceview.htmlrtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com3tag:blogger.com,1999:blog-4339544753706943601.post-22877767789449337002009-05-19T01:22:00.000-07:002009-05-19T01:25:17.574-07:00fdatasync not found in bionic libcfdatasync(int) declare is found in bionic/libc/include/unistd.h, but it is not actually implemented in libc. I can NOT find the fdatasync symbol in /system/lib/libc.so.rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com4tag:blogger.com,1999:blog-4339544753706943601.post-7446539845742867172009-02-26T20:22:00.000-08:002009-02-26T20:25:11.994-08:00UI/Application Exerciser MonkeyThe Monkey is a program that runs on your emulator or device and generates pseudo-random streams of user events such as clicks, touches, or gestures, as well as a number of system-level events. You can use the Monkey to stress-test applications that you are developing, in a random yet repeatable manner.<br />Basic usage of monkey:<br /><blockquote>usage: monkey [-p ALLOWED_PACKAGE [-p ALLOWED_PACKAGE] ...]<br /> [-c MAIN_CATEGORY [-c MAIN_CATEGORY] ...]<br /> [--ignore-crashes] [--ignore-timeouts]<br /> [--ignore-security-exceptions] [--monitor-native-crashes]<br /> [--kill-process-after-error] [--hprof]<br /> [--pct-touch PERCENT] [--pct-motion PERCENT]<br /> [--pct-trackball PERCENT] [--pct-syskeys PERCENT]<br /> [--pct-nav PERCENT] [--pct-majornav PERCENT]<br /> [--pct-appswitch PERCENT] [--pct-anyevent PERCENT]<br /> [--wait-dbg] [--dbg-no-events]<br /> [-s SEED] [-v [-v] ...] [--throttle MILLISEC]<br /> COUNT</blockquote>Example: adb shell monkey 1000<br />#send 1000 events to all applicationsrtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com2tag:blogger.com,1999:blog-4339544753706943601.post-65938470971302461342008-12-10T20:29:00.000-08:002008-12-10T20:33:17.679-08:00Tips to import sample Android projects to EclipseI am a newbie to Eclipse and Android applications development. I installed the Eclipse yesterday and tried to take a look at the Android sample to start with. I had problems to import sample project into Eclipse. Google is always the one I first tried. I found this article: <a href="http://androidcommunity.com/forums/f4/how-to-import-sample-android-projects-to-eclipse-109/">How to import sample Android projects to Eclipse</a>. It is helpful to me. I think it will also be helpful to others.<br /><blockquote>Here is the tips: Simply create project from existing source (then use "Browse" to select sample shipped with SDK). </blockquote>rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com12tag:blogger.com,1999:blog-4339544753706943601.post-65377201879377166812008-12-07T18:37:00.000-08:002008-12-07T18:40:39.194-08:00Nokia N810 with android portedPeter McDermott has an article about the process of porting android to the Nokia N810. Quite a lot of helpful information included.<br /><br /><a href="http://www.nthcode.com/pubs/porting-android-to-a-new-device.html">http://www.nthcode.com/pubs/porting-android-to-a-new-device.html</a>rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com4tag:blogger.com,1999:blog-4339544753706943601.post-71659420914029805642008-12-07T18:32:00.000-08:002008-12-07T18:37:02.815-08:00Kogan Agora Pro is the next android handset<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvpsRPvVTztlBjhqR4_etatpu2uLkbAset8-E4HcIl7_oAXgJ_39vl9w97VheKFpoUKWAYnOwYIuOJiCrBxs3qgamu8DbzJep0kWpVfREJNEv9R-mR4eh4W-muGeWzc00fjeV3h-9i7yg/s1600-h/atte1ab1.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 204px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvpsRPvVTztlBjhqR4_etatpu2uLkbAset8-E4HcIl7_oAXgJ_39vl9w97VheKFpoUKWAYnOwYIuOJiCrBxs3qgamu8DbzJep0kWpVfREJNEv9R-mR4eh4W-muGeWzc00fjeV3h-9i7yg/s400/atte1ab1.jpg" alt="" id="BLOGGER_PHOTO_ID_5277242569170452498" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />The Kogan Agora Pro has popped up in Australia as the latest android handset and is available for international pre-order. The phone has a 2.5 inch resistive touchscreen, QUERTY keyboard, 3G and GPS for $399.<br /><blockquote><span style="font-weight: bold;">HIGHLIGHTS:</span><br />· 2.5-inch TFT-LCD flat touch-sensitive screen<br />· Integrated QWERTY keyboard<br />· High-speed 3G network connection<br />· One-Touch Google Search ™<br />· Easy Web Browsing<br />· Easy-to-use email with attachment support for images, videos, music and documents<br />· Customisable Home Screen with instant Email, text message and IM notifications<br />· Instant access to mobile Internet services (Gmail ™, YouTube ™, Google Talk ™, Google Calendar ™, Google Maps ™)<br />· Music Player<br />· microSD™ expansion slot for all your storage needs<br />· Wi-Fi network access (included with Kogan Agora Pro)<br />· GPS navigation capability (included with Kogan Agora Pro)<br />· 2.0 megapixel camera (included with Kogan Agora Pro)</blockquote><a href="http://gizmodo.com/5101708/kogan-agora-pro-is-the-next-android-handset">http://gizmodo.com/5101708/kogan-agora-pro-is-the-next-android-handset</a>rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com0tag:blogger.com,1999:blog-4339544753706943601.post-70894606866205785912008-12-07T18:25:00.000-08:002008-12-07T18:29:24.931-08:00Android Dev Phone 1 for developersThe Android Dev Phone 1 is a SIM-unlocked and hardware-unlocked device that is designed for advanced developers. The device ships with a system image that is fully compatible with Android 1.0, so you can rely on it when developing your applications. You can use any SIM in the device and can flash custom Android builds that will work with the unlocked bootloader.<br /><br />The device currently costs $399 (USD) (including free shipping in the US), and will be available for purchase in 18 international markets, including the US, UK, Germany, Japan, India, Canada, France, Taiwan, Spain, Australia, Singapore, Switzerland, Netherlands, Austria, Sweden, Finland, Poland, and Hungary.<br /><br />More information, see <a href="http://code.google.com/android/dev-devices.html">http://code.google.com/android/dev-devices.html</a>rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com0tag:blogger.com,1999:blog-4339544753706943601.post-33695544739286934852008-12-03T00:03:00.000-08:002008-12-03T00:13:39.150-08:00struct ipv6_mreq has no member named ipv6mr_interfaceWhen I am porting ffmpeg to Google Android, I got an error: 'struct ipv6_mreq' has no member named 'ipv6mr_interface'. I dont understand what happened. When I google the related information, I got this article: <a href="http://lkml.indiana.edu/hypermail/linux/kernel/0106.1/0080.html">Linux kernel headers violate RFC2553</a>. The corresponding header file is bionic/libc/kernel/common/linux/in6.h. I have to correct the usage of ipv6_mreq.ipv6mr_interface into ipv6_mreq.ipv6mr_ifindex.<br />What I am concern is does Bionic libc use the ipv6_mreq structure in a correct way?rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com9tag:blogger.com,1999:blog-4339544753706943601.post-88840085366760816672008-11-24T21:01:00.000-08:002008-11-24T23:32:36.807-08:00Android build systemFound document in android open source. They are in myandroid/development/pdk/docs/. Following information are from the "Android build system" section. It is more helpful than "<a href="http://discuz-android.blogspot.com/2008/11/add-new-component-into-open-source.html">Add a new component into open source Android</a>".<br />A makefile defines how to build a particular application. Makefiles typically include all of the following elements:<br /><ol><li>Name: Give your build a name (LOCAL_MODULE := <build_name>).</li><li>Local Variables: Clear local variables with CLEAR_VARS (include $(CLEAR_VARS)).</li><li>Files: Determine which files your application depends upon (LOCAL_SRC_FILES := main.c).</li><li>Tags: Define tags, as necessary (LOCAL_MODULE_TAGS := eng development).</li><li>Libraries: Define whether your application links with other libraries (LOCAL_SHARED_LIBRARIES := cutils).</li><li>Template file: Include a template file to define underlining make tools for a particular target (include $(BUILD_EXECUTABLE)).</li></ol>The following snippet illustrates a typical makefile.<br /><blockquote>LOCAL_PATH := $(my-dir)<br />include $(CLEAR_VARS)<br />LOCAL_MODULE := <buil_name><br />LOCAL_SRC_FILES := main.c<br />LOCAL_MODULE_TAGS := eng development<br />LOCAL_SHARED_LIBRARIES := cutils<br />include $(BUILD_EXECUTABLE)<br />(HOST_)EXECUTABLE, (HOST_)JAVA_LIBRARY, (HOST_)PREBUILT, (HOST_)SHARED_LIBRARY,<br /> (HOST_)STATIC_LIBRARY, PACKAGE, JAVADOC, RAW_EXECUTABLE, RAW_STATIC_LIBRARY,<br /> COPY_HEADERS, KEY_CHAR_MAP</blockquote>rtmhttp://www.blogger.com/profile/15941083362450228950noreply@blogger.com2