Friday, January 27, 2012

Samsung Galaxy Tab 10.1 - Stuck on Boot (link to article)

My Samsung Tablet "has died" today. It got stuck on boot for some reason.
I hooked it up to the computer and checked the logcat (adb logcat). 
It was trying to open the account database on the device, that for some reason got corrupted and after the failing to do so (unable to open database file, db=/data/system/accounts.db) it rebooted over and over again. The database can be easily fixed on the rooted device, but mine was not rooted yet.

After a bit of googling I found this useful article that describes exactly the same problem on exactly the same device and provides the solution:

Essentially, the solution comes down to deleting all the user data (aka factory reset), here are the steps from the article:

"In case you are wondering how to hard-reset your tab, you can follow these steps:
1) Power off the device by holding the power key for about 8 seconds
2) Press the volume down key (the one to the left, as I always confuse them) and then the power key
3) Within a couple of seconds, you'll see two logos on the device, one for USB and another, that looks like a Android dude shoveling earth
4) Press the the volume down button to select the the USB icon, and then press the volume up button to make the actual selection
5) Your device is now in the "fastboot" mode
6) Finally, open up your terminal/shell and type fastboot -w, which will completely erase your userdata and cache partitions (took about 12.5 seconds for me). I got the fastboot by building it from source, but you can download pre-built binaries from various sources on the web
7) Restart your device
8) You should now be prompted to set it up... all over again"

Many thanks to the author of that article Aleksandar Gargenta. 

Javascript from command-line on Mac OS X

Here is a "trick" to get the javascript command-line tool "jsc" available on Mac OS X,  just add a link, for example like this:
sudo ln /System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc ~/bin/jsc
then just run "jsc".

Friday, January 13, 2012

YAML parser for Android

I needed YAML parser for Android this week and after a bit of research I found that SnakeYAML might work: http://code.google.com/p/snakeyaml
The only problem was if you try to use the latest code the application would fail with exception that looks something like this in the logcat:

VFY: unable to resolve exception class 21 (Ljava/beans/IntrospectionException;)


This happens due to the dependency on java.bean package APIs that is used to parse getters/setters types of properties (methods). 
There is a prebuilt library already available in the download section for version 1.8 adjusted for Android: http://snakeyaml.googlecode.com/files/snakeyaml-android-1.8-SNAPSHOT.jar (thanks to Alexander Maslov), but I wanted to use the latest code. 
The adjustment for Android is quite straight forward:
* Remove all the imports of java.bean package components
* Remove the throws IntrospectionException from methods declarations in few files (grep, there are only 4 .java files to change 
* In the introspector/PropertyUtils.java adjust the getPropertiesMap method implementation, throw away the use of Introspector. Yep, the library will not support java getters/setters methods serialization after that, only fields, but that worked fine for me.
* Remove introspector/MethodProperty.java file
* If you want to save some time and don't care building and running tests (I know it's wrong, but still), then you can build the .jar library with mvn package -DskipTests=true command.
* Add the final .jar file into your Android project and enjoy YAML on Android

Update (02-22-2012):
Alexander just landed the patches for Android (http://code.google.com/p/snakeyaml/source/list).
Now the latest source code can be easily built with one command: mvn package -Pandroid or to skip the tests mvn package -Pandroid -DskipTests=true. After the build,  just use snakeyaml-1.11-SNAPSHOT-android.jar.

PipedInputStream default size on Android

The PipedInputStream on Android is 1024 bytes by default.

protected static final int PIPE_SIZE = 1024;

In many cases this value is too small, so the constructor with the size parameter should be used instead.

Thursday, January 12, 2012

Android application signing with PKCS12 (.p12) certificate

Here are few useful commands to sign the Android application with PKCS12 certificate.

* Import PKCS12 cert into keystore file:
keytool -importkeystore -srckeystore mycert.p12 -destkeystore mycert.keystore -srcstoretype pkcs12

* Change the certificate alias in the keystore if you like:
keytool -changealias -keystore mycert.keystore -destalias new_cert_alias -alias original_cert_alias

* List the keystore certificates (-v for verbose)
keytool -list -v -keystore mycert.keystore

* Sign the Android APK
jarsigner -verbose -keystore mycert.keystore myapp.apk cert_alias

* Verify that the APK is signed
jarsigner -verify -verbose -certs myapp.apk



OAuth2 with Google C2DM (push)

I had to implement the server prototype for Google C2DM (push) the other day.
The easiest option to get the auth token is to use ClientLogin API: http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html  that returns the auth token in one call. One of the problems with this approach was that I either had to store the credentials on the server in order to refresh the auth token if it expires or notify the system administrator to go ahead and re-authenticate through the dedicated web page on the server. 

The better approach is to use OAuth2 API instead: http://code.google.com/apis/accounts/docs/OAuth2WebServer.html
There are couple of things are not well documented:
* When you register the app on the https://code.google.com/apis/console/ there is no C2DM service API to choose. That's fine for now, though it might change later probably.
* One of the parameters "scope" for the https://accounts.google.com/o/oauth2/auth call needs to be set to 
scope=https%3A%2F%2Fandroid.apis.google.com%2Fc2dm (https://android.apis.google.com/c2dm url-encoded)
* Set parameter access_type=offline.This will provide you with the refresh_token in the authentication response, that you can use to renew the auth token when it expires. 

Hope this will save somebody few minutes. 

UPDATE (January 19, 2012):
If you stumble upon the MismatchSenderID error, make sure that when you start authentication (https://accounts.google.com/o/oauth2/auth) that you are not already signed in under your personal google account (hint: the browser cookies) . You should be signed under the google account that you created and that got approved for C2DM.



UPDATE (July 2, 2012):
As of the Google IO 2012 the C2DM API is officially deprecated and this article is not really that relevant anymore.
The new sign ups and the quota increase requests are not going to be processed anymore and Google highly recommends to migrate over to the Google Cloud Messaging (GCM), which is still free and has lots of improvements and additional features. I personally think GCM is awesome. 
Please refer to the official GCM page for more details:
http://developer.android.com/guide/google/gcm/index.html
I'm looking forward to change my code to work with GCM pretty soon and will try to write another post on the transition process. Enjoy!

Wednesday, January 04, 2012

Friday, December 30, 2011

Missing pthread_mutex_timedlock on Android

I stumbled upon a problem today that the pthread_mutex_timedlock function definition is missing on Android, though it's declared in the pthread.h.
The first thought was to implement it as a loop with a call to pthread_mutex_trylock and some sleep until we are able to get the lock or until the timeout happens, felt a bit awkward.

I took a look a the Mono for Android source code and that's exactly what they do there (./mono/io-layer/mono-mutex.c), so go figure, looks like this solution might not be that bad after all.


Here is how it's implemented in Mono for example:
int
pthread_mutex_timedlock (pthread_mutex_t *mutex, CONST_NEEDED struct timespec *timeout)
{
 struct timeval timenow;
 struct timespec sleepytime;
 int retcode;
 
 /* This is just to avoid a completely busy wait */
 sleepytime.tv_sec = 0;
 sleepytime.tv_nsec = 10000000; /* 10ms */
 
 while ((retcode = pthread_mutex_trylock (mutex)) == EBUSY) {
  gettimeofday (&timenow, NULL);
  
  if (timenow.tv_sec >= timeout->tv_sec &&
      (timenow.tv_usec * 1000) >= timeout->tv_nsec) {
   return ETIMEDOUT;
  }
  
  nanosleep (&sleepytime, NULL);
 }
 
 return retcode;
}

Wednesday, December 28, 2011

... из жизни


Сегодня на обеде видел одного папашу с маленьким ребёнком (меньше года). Дядька это болтал с двумя тётками которые сидели с ним за столом, пил большую банку Monster Energy Drink и тряс коленкой на которой сидел ребёнок ну наверное с частотой не меньше 300 ударов в минуту, так что казалось что у ребёнка либо голова отвалится, либо будет обширное сотрясение мозга.
"Энергетики" это вам не игрушка....



Nouns vs Verbs

Stumbled upon this post today,  it's almost 6 years old, but I haven't seen it before and enjoyed reading it quite a bit:

Execution in the Kingdom of Nouns

Hope you like it too.

Monday, December 26, 2011

Говорят дети


Саша просит поиграться на таблете:
- Хочу игру где убивают злых поросят ...

(Angry Birds)

Friday, December 23, 2011

How to setup Eclipse for debugging with Android NDK


Just wanted to bookmark couple of useful links on how to setup Eclipse IDE for debugging with NDK. Sometimes it might be more convenient than doing ndk-gdb from terminal, that I still didn't quite get used to yet. It took a bit of time and few tries to get things going. I had some problems with symbols loading and matching, and finally succeeded. Anyways if stuck check comments to these articles. 
  1. Setup your project to be a mixed Java, C, and C++ project:
  2. Setup your project to enable debugging:

Thursday, December 08, 2011

Хочу как у мусорщика


По дороге в детский садик, Саша позади в детском сиденье возится с кепкой.
Я: -Саша ты что там с кепкой делаешь.
Саша: -Хочу как у мусорщика.....

... и одевает кепку набок ...

... а ведь было же время когда завораживали мусорные машины с автоматическими подъёмниками, строительная техника и т.д. ... поменялись с возрастом интересы и приоритеты как-то ....

Friday, December 02, 2011

Android NDK logging

Just wanted to share the snipped that often used in the different Android native projects.
The following are some useful macros for logging with NDK.

#include<android/log.h>

#define LOGD(LOG_TAG, ...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGV(LOG_TAG, ...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
#define LOGE(LOG_TAG, ...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

You can define more as needed just take a look at the android/log.h header file for all available priority values.
Then I would usually define log TAG:
#define LOG_TAG "MyModule"

and use the macros like this:
LOGD(LOG_TAG, "my val: %s", val);


fopen with native library on Android

If you develop an Android application with some native C/C++ layer (NDK) and 
try to open the file from it by doing FILE *pFile = fopen ("myfile.txt" ,"w");
the fopen call will fail.

The reason is that the current working directory for you application is the root of file system '/' and naturally your application doesn't have access to it.

In order to fix this problem you have to pass the full path for the file to fopen call.
One way to do this is to pass the base path to your application data folder where your application has read/write permissions. For example you can use the Context API getFilesDir().getAbsolutePath()
and pass the result to the native function call.
This particular API resolves currently into something like: "/data/data/[app package]/files/"

In your native code then the fopen call should succeed with 
FILE *pFile = fopen ("/data/data/[app package]/files/myfile.txt" ,"w"); 

Hope this was helpful.

Friday, November 18, 2011

Improved Git development model

If you are just starting to utilize Git in your team I would highly recommend to take a look at the git-flow https://github.com/nvie/gitflow and read the following article:
http://nvie.com/posts/a-successful-git-branching-model/

Enjoy!

Thursday, November 17, 2011

More fun with Android NDK7

I tried to compile cURL library Android NDK7 for x86 architecture and it looks like though the bug was reported in NDK6b: http://code.google.com/p/android/issues/detail?id=19851, the libc is still missing few functions sigsetjmp and siglongjmp.
The easiest solution for me was to get the libc from the latest ICS source tree (built for x86 arch).
Looking forward to get this fixed in NDK8, hopefully before Christmas.


if you are using sem_timedwait on iOS or Mac OS X ....

While porting some C/C++ code to iOS found out that sem_timedwait is not implemented on iOS or Mac OS X and seems like on many BSD systems. Here is the discussion on the topic:
http://stackoverflow.com/questions/641126/posix-semaphores-on-mac-os-x-sem-timedwait-alternative
The discussion a bit old but it seems like it is still a valid one.

For now I conditionally compiled the code with the call sem_wait, will look into a better cross-platform solution later.

Wednesday, November 16, 2011

Native libraries porting to iOS

Recently I spent a bit of time working on porting (getting built) some native libraries with Android NDK and iOS. The port to Android NDK deserves it's own post, that I might write down later.

As for iOS, I primarily needed openssl, curl, zlib and found nice little script, that helps you with the build:
http://code.google.com/p/ios-static-libraries. Just comment out what you don't need and you should be good to go. It's quite easy to repurpose the script to pull the source from your local repos if needed.

One of the problem I had was that I have only iOS SDK 5.0 on the machine and the libcurl build for iPhone device was breaking because "cpp" compiler (export CXXCPP=${DEVROOT}/usr/bin/cpp
) was not found . Apple provided "cpp" compiler for the emulator, but conveniently left it out from the iPhone device toolchain. The easy fix for that is to create the symbolic link in the /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin directory:
ln -s llvm-cpp-4.2 cpp

Hope this saves you a bit of time.