Friday, November 30, 2012

ICS, JB Phone window manager difference:

while playing video on fullscreen, status bar will be hided during playback in JB. This will not happen with ICS.
In ICS, Window manager will check for the mStatusBarCanHide flag to identify whether the system is having Phone UI or Tablet UI.
If it is having Phone UI, mStatusBarCanHide flag will be set to true. Whereas in case of tablet, this flag will be set to false.
Based on this flag, window manager differentiate the Phone UI or tablet UI.
   Display 600 dp is Phone UI.
   Display 720 dp
   Display > 720dp, tablet UI or larger screen UI

In ICS, status bar hiding support is available only phone models. It is not available for tablet UIs.[Refered from android ICS release notes]
In JB, it will checks for the mHasSystemNavBar. This value indicates whether device is having tablet UI/larger screens or smaller UI/phone UI.
This flag will be set to true for tablet UI.

      One more major difference between ICS  and JB is that while playing video on fullscreen, ICS will hide the status bar by calling status bar service's collapse() method whereas in JB, it will change the window manager layout.window manager layout's display frame/navigation frame/content frame will be set the video screen. Ideally status bar will be there in screen but it wont be shown to user due to display viewport.

Thursday, November 29, 2012

How Wifi/ethernet/3G  service is working in android:
===================================


   1) while bootup, connectivity service will launch all networking services.
 
In android, most of the system services cant be directly interactable by user applications/any other medium.
 Every service will have a manager which will talks with service. For example, To interact with connectivity service, Connectivity manager is available. User/application will query for the available network connections from Connectivity manager.

   In the same way, wifi manager is available for Wifi service, Window manager is available for Window service and so on.
During bootup, System server launches connectivity service.connectivity service launches/initiates wifi/3G/ethernet services.

     To receive whether the link is up or down, ethernet connection is connected or disconnected, we will receiving notifications from
framework.[android_net_wifi.cpp/android_net_   ] This framework file watches for network connectivity by reading /proc or sys file system.

    if wifi is available then under proc/net/wireless/wlan0 interface will be created. So the framework will waits for proc/net/wireless/ file for any changes.
    More over we will get notifications from driver on link up or down information. Once the link is up, it will be updated to Mobile/Wifi/ethernet trackers. These trackers will query for the network information like DHCP IP address,netmask and so on from DHCP service/dhcp daemon.
  
   Once the wifi/mobile state tracker got an IP address and necessary information about the network it update to Connectivity manager.
Meanwhile it will also update the Wifi/Ethernet manager which will talks to wifi/ethernet/3G services  .
    
    UpdateConnectivity of connectivity manager is being called to update the CONNECTED /DISCONNECTED network information to connectivity service.
 
   while user application queries for connected network information from connectivity manager, Connectivity manager will get this information from connectivity service.
     If multiple network connections are available, Connectivity service will decides which one to choose for network connection.
For example, if we have 3G connection, we reached into Wifi area, Wifi can download more data compare to 3G. So Wifi connection will be selected for network connection, 3G connection will be teared down.
    Every network has priority based on priority it will choose the desired connection.

  In linux and all, Ethernet/Wifi connection is possible at the same time. But the kernel will make use of any one interface[wifi/ethernet] at a time.

   wifi state tracker will make use of DHCP daemon to get dhcp ip address. For Dhcp request, Some class is available which will calls system/core/libnetutils library. which will talks to dhcp daemon initiated from init.rc.

           This DHCP daemon will query the ip address and set the IP address,netmask information in system properties [dhcp.wifi.ipaddress,dhcp.wifi.netmask]. If the Wifi state tracker doesnt receive any dhcp response for a particular timeout period, it will report timed out error. If dhcp reply is received it will reads Ip address and netmask from the given interface and update it on settings.
     CONNECTIVITY_ACTION is an intent which will be used to update the network information from connectivity manager/service.
  

Saturday, November 24, 2012


How to maintain various versions with the same target binary inside android file system ???


In Android, whatever folders with Android.mk files are added to external folder in android file system,while building the android, it will be compiled.

   I faced an interesting problem.  Wifi need wpa_supplicant. There are multiple wpa_supplicants are available in external folder. I could not figure it out which one will be compiled.
   external/wpa_supplicant
   external/wpa_supplicant_6
   external/wpa_supplicant_8

Because whatever things we copied to external folder, if it has Android.mk, then that folder will be compiled.
All 3 folders are having same target binary [wpa_supplicant,wpa_cli]. If we have multiple target binary with the same name, compilation will fail.

I analysed and found that in device.../BoardConfig.mk will have the macro to specify the WPA_SUPPLICANT_VERSION=0_x_8.0

if the WPA_SUPPLICANT_VERSION is 5.0, wpa_supplicant folder will be compiled.
if the WPA_SUPPLICANT_VERSION is 6.0, wpa_supplicant_6 folder will be compiled.
if the WPA_SUPPLICANT_VERSION is 8.0, wpa_supplicant_8 folder will be compiled.

within the external/wpa_supplicant/Android.mk if the WPA_SUPPLICANT_VERSION == 0_x_5.0, then only the folder source codes will be compiled.
within the external/wpa_supplicant6/Android.mk if the WPA_SUPPLICANT_VERSION == 0_x_6.0, then only the folder source codes will be compiled.
within the external/wpa_supplicant8/Android.mk if the WPA_SUPPLICANT_VERSION == 0_x_8.0, then only the folder source codes will be compiled.
Target android board can have any supplicant version, it might be 5.0 /6.0/8.0.


   Lessons learnt:
  
   we can have multiple versions of the same binary under external folder,decide which version to be compiled based on target board.

  where I can apply:

     Assume that TI android board has various accelerators for display.Some TI boards will use x hardware accelerators for display. Some boards will use Y hardware accelerators for display. We can use same target binary  so it can either use x hardware accelerator or y hardware accelerator for display based on BoardConfig. Finaly display binary is same.

 we can not put only x hardware accelerator source code in android. It will fail while compiling for Y hardware accelerator source.
User has to take care of copying the code based hardware accelerator. Or else we can copy x and y hardware accelerator code and decide which
one to be compiled by boardconfig.mk macros .



 

Friday, November 23, 2012

Problem in static IP:
===============


I ported the android x86 ethernet support to android board.
I used the same kernel to run ICS and jellybean OS.
I faced  the problem in setting static IP. while switching from DHCP to Static IP, entire system hangs.
 Ethernet patch is storing the value in Settings. while reading the value from settings and setting the static IP, it hangs...
Since ethernet is configured in bootup time, system hangs and doesnt proceed booting android.

    I analysed and found that providers/settings data will be stored in /data/data/com.android.settings.provider/settings.db.
All android applications/providers database values will be stored under /data/data/com.android.ApplicationName.
To clear the settings value, we can format /data/ partition , So that stored information will be deleted.
Now I am able to proceed with booting android.
   But still problem is there while setting static IP.I doubted the network environments/OS/my program.

  1)Through ifconfig, I am able to set static IP address. So there is no problem in network environment.    
  2) I doubted IP settings are not allowd in jellybean, any  new services have been added to change IP address. Since I am using same kernel, there wont be any changes in kernel level.
  3) I doubted my entire program is not working. But same code was previously working with ICS.

Previously with ICS, I am able to set static IP and tested well.Same code is not working. I doubted my static Ip setting itself is not working.
 To narrow down the issue, I hardcoded the netmask value, afterwards it is able to set static IP.
  In my code, I debugged and found that it is hanging in netmask to prefix conversion which is required for setting static IP address.

 Lessons Learnt:  1) All android applications store data/database values under /data/data/com.android.ApplicationName[Package name of the android]
  2) Always document the sample inputs/environments for success cases, So in future, if the system is failing, we can try with that input.
  3) always test lower limit and upper limit values... System hangs since It is failed in lower limit

 Please refer my previous post about netmask to prefix conversion problem.
http://sundararajana.blogspot.in/2012/11/netmask-prefix-length-netmask-is-also.html




   

Thursday, November 22, 2012

Netmask , prefix length :
==========================

  netmask is also measured as prefix length. The number of bits set in netmask value is called as prefix length.
Example :   Netmask:255.255.255.0 Prefix : 24 //number of bits set in 255.255.255.0 value.

 To convert the netmask to prefix I added below code in Java:

  netmask= lookupHost("255.255.255.128");
   while ( netmask !=0)
   {
      if( netmask & 1)
        ++prefixLength;
       netmask = netmask >> 1;
    
   }

  Simple code :
     The above code is working fine for sometime. Sometimes it is not working...
    I found that netmask to prefix conversion is breaking and makes the system hangs....

 The input 255.255.255.0 is working fine. But 255.255.255.128 is breaking ...

Finally figured that the problem is with the code.

    In a 32 bit signed integer, 255.255.255.0 is not giving any problem. So LSB is stored as a first byte in memory ...

   lookupHost converts the string as 0 255 255 255[bits set] as integer..[0x00ffffff].
when it comes to 255.255.255.128, 128 255 255 255 [bits set as 0x80ffffff. So netmask will always not equal to 0, So it is in infinite loop.
>> shift operator operates on bits not on sign bit. netmask's sign bit will always 1 & it satisfies netmask != 0 condition infinitely.

Solution:
   To avoid this problem,
    1)I have to use >>> operator which will also operates on sign bit.
    2) I can also check for the maximum limit.

   Above code can be modified as below:

      
  netmask= lookupHost("255.255.255.128");
   while ( netmask !=0)
   {
      if( netmask & 1)
      {
        ++prefixLength;
         if (prefixLength == 32)
         {
           break; //exit while loop since maximum allowed value is reached for prefix length for 32 bit IP address, maximum prefix len is 32
         }
      }
       netmask = netmask >>> 1;// >>>     Unsigned right shift
         
   }

Wednesday, November 21, 2012

Practice Programming[ About Perfect Practice]:
http://codekata.pragprog.com/2007/01/code_kata_backg.html

Monday, November 19, 2012

Android logcat with Process ID and Thread ID:
         Android logs can be printed with Process ID and thread ID.

Command to print logcat with PID and TID:

   /system/bin/logcat -v threadtime

When it will be useful ?

     1)  If any crash is occured, we can identify which thread or process id is crashing. we can enable logs in all the modules. If we got any logs from crashing  thread, then crashing thread and logs  TID and PID will match . Based on it, we can localize the crashing location/thread.

  2)   PID and TID will be useful to check which  framework classes used by application.  For example, If I want to check audio track is used by application or not. I can enable logs in audio track class. While printing logs, it will show the process id and thread ID for Audio Track class.

  we can match the PID with running applications PID  to figure it out.

  otherway is we can decompile the APK binary to source code to check whether AudioTrack/framework class is used.


Android APK to java source code conversion:
==============================
Required tools for conversion:
  i) 7zip ii) dex2jar iii)jd-gui [java decompiler GUI]


1)Rename the .apk file to apk.zip.
2)unzip using 7zip software to folder.
3)unzipped folder will have classes.dex file
4)use dex2jar to by below command:
    dex2jar "D:\classes.dex"
  This will create the jar file in "D:\classes_dex2jar.jar".
5)run jd-gui and  open "D:\classes_dex2jar.jar" jar file.
    This will give you the source code of the APK.

  From jd-gui, we can do File->Save All sources . So that all sources are saved as zip file.Unzip the file to get the source code.

Sunday, November 18, 2012

Running/Launching Linux/Android OS with  same kernel, Is it possible How to do?:

In Embedded/STB devices, Mostly they will be using the Linux OS.
Now they are moving to android. How it is possible for them to move to linux???

  over the Linux kernel, Some patches/changes are applied and it is called as android kernel. They are having separate branch also.
 To run android, Below Components involved:
    bootloader, kernel,android source code compiled binaries

    we have to compile kernel with target[ARM /x86] architecture. In the same way we have to compile android source code to the target architecture[x86/ARM].

   Initially the bootloader will loads kernel. Kernel will starts init process of android.

This init process will loads init.rc, init_board.rc scripts and also launches all the android services.

   The user can load linux/android OS with same kernel.

we can have a script to launch android/linux OS or based on user choice.

In launching an android script, we have to run android init processes in background;

android_launch.sh
  ./androidbin/init & # This init binary is generated from android source code.

  The target device should have all the android binaries.
        
 Linux also have the same script.
 
linux_launch.sh
   ./linuxbin/init &

   Linux source code also has init source code. This should be invoked if we want to launch the linux.This init process will launch all linux binaries.
The device should have all the linux source code compiled binaries.