Monday, September 22, 2014

Android: What to test

Recently i was trying to note down all the testing requirements for our Android application.  While trying to get down all the bits and pieces and i find out that most of the dev team members exactly know what to test when its come to point of traditional testings like Unit or Regressions. But for an Android app there are some additional things to test. Things or problems can happen only on a Android powered mobile device.

To make the whole list complete i note down requirements in two different groups.
  1. Android Specific: In this test cases we primarily focus on issue can only happen to an Android application.
  2. Traditional Testing: These are the trivial test cases what we see everywhere as part of standard software practices.

Group A: Android Specific

ANR

Description: Android display, Application Not Responding (ANR) when input events failed to respond in 5 seconds and Broadcast Receiver has not finished within 10 seconds. 
How to Test: Can be done by wiring java code. Or using DDMS.

Automation: Depends on method of investigation.  

Links
2.       http://stackoverflow.com/questions/704311/android-how-do-i-investigate-an-anr

Cycle: It is important that we test this in every build cycle. 


Memory Analysis

Description: Android application has memory quote regardless of available physical memory on a device. This number varies from device to device. This is done, so that non critical application cannot take over the device memory and eventually critical application fails.  This means reusing memory is  key to an Android application life-cycle. This is relatively easy task as  Garbage collection is part of Dalvik VM, but there are instances where Garbage collection does not really work. For example,

On 2.3 and prior devices bitmap allocated on native layer. Developer need to use explicit code to free that memory.

·         System.gc() on android is not an instruction to Garbage collector, it’s an hints where Dalvik will decide whether it will collect garbage or not. It is an error to assume that after execution of that code all memory became free.

·         Memory also builds up very fast in case of a memory leak with respect to device configuration changes. And, important to not that, device configuration change not limited to screen rotation.

Goal: To find out, if equal amount of free memory is equivalent after every Activity or Android components or java objects destroyed.
Tools: DDMS can be used for this. Furthermore, MAT (Eclipse memory Analyzer) is also a great tool when it comes to investigate java object creation in memory.
Automation: We can add additional code to monitor memory allocation and deallocation. But this additional code might impact on the performance of original code base. We can use manual QA to investigate memory usage. 
Links
2.       https://developer.android.com/tools/debugging/debugging-memory.html

Compatibility Testing

Device manufacturer tend to customize devices as they see fits. It creates software and hardware fragmentation on many levels. Heap memory changes from device to device and so does device screen density.  Android manifest provide a good filter for hardware of system features but user can still install an app avoiding such filters, and, in some cases filters just not enough.
 Services: Some app rely on Google services like PUSH or MAP. Some device manufacturer may have own similar sets of services or use some other third party services. In such cases some functionality will not work or will produce unexpected result. FYI, Google services are not part of Android frameworks and all android device may not ship with same sets of services. For example Amazon uses its own Push and Map service. 

·         Hardware Features: Some App rely on device hardware features. For example, If your application requires device back camera or may be auto focus in a camera to function properly, you need to make sure that device has that features or not.
 
·         System features: Android provide standard framework for all device manufacturers to follow. Intention that Android OS, can be adopted with minimal set of changes on any hardware. But, there are cases where device manufacturer do not follow any standard.  Device back button could be a such good example. Amazon fire phone do not have back button. 

·         Software feature: If you app depend on additional Software feature Example: Open GL, you have to make sure, that feature is really available on that device. 

·         Third party library: If you have a third party library, you need to test if that third party library also compatible.

·         User Interface: Screen density and resolution is different on each device. In case of native UI we need to make sure that those are scaled properly on every devices.   

·         WebKit: There are always some issues with HTML content and webkit engine. We need to make sure that device Webkit version is compatible with developed web contents and Webkit can render all HMTL elements without issue and Java Scripts are fully functional.

Automation: Not possible. Require manual QA input.

Cycle: Once for every new device


Failsafe testing

Android mostly rely on Asynchronous messaging (Intent) to report any system events. So, sudden changes on system status require some time to propagate. Every android application should have proper code in place to handle this type of exceptions.

Goal: Focus on this test is to figure out if application can shutdown gracefully without its required critical hardware and software components. An application should not crash under any circumstances.

·         Network: Data fluctuation on mobile phone is very normal scenario. Things to test
o   Not connected
o   Aeroplane Mode
o   Device connected to a network but no data. 
o   Data connection switching from Wi-Fi to Mobile network.
·         Memory
o   Limit test: what happened when application reaches it allocated heap memory quote. Usually user from older device will face this type of problem.
o   Allocation test:  In this scenario device do not have enough physical memory to allocate heap memory. Can happen with newer or older devices. For example, newer device comes with lots of preinstalled apps and Android has tendency to provide priority to app signed by system certificate. This gets more complicated when foreground app is not a system app. 

·         Service: What happened when device do not have required third party services or all third party service become unavailable due its error. Ex, Google GMS

·         External storage: There are cases when Android system keep switching between mount unmount state. If App rely on an external storage, we have to make sure that it dosen't crash when there are none. 

Comment: This can be done in any QA environment at least once per release cycle.  

Automation: Not possible specially when we need turn on off device settings. Require manual QA input. 

Group B: Traditional

Unit Test

Goal: To test individual piece of code works as intended.
Things to tests
·         Boundary Values, Empty and NULL
·         Every method(private included), class
·         Singleton
·         Thread
·         Memory allocation/Deallocation
+  what ever required by your organization software development practices.
Automation: can be done as part of build process.

Cycle: Once per build Cycle

Recommendation: Android provide Android Unit test framework to test individual piece of code. It is originally derived from Junit.  


Use Case Test

This type of testing can automate a complete use case. For example login flow, or a particular use case from start to end.  Android test framework provides Instrumentation to start an application, or to click a button or fill an input field with pre-determined text. In case of hybrid application currently Selendroid and Robotium both provide full feature test support.
Automation: can be done as part of build process.
Cycle: Once per build Cycle


Stress testing

Currently android provide tools which can generate pseudo random event to a target application. A script can run overnight on an app and collect log. Based on your organization policy, you do any of the followings
  • Ask QA to investigate and reproduce relevant crashes; if reproducible add the defect to an issue tracker
  • Ask Dev to investigate crashes and add to issue tracker if necessary
 Requirement: Device/Emulator needs to be connected to a machine which will run the script.

Limitation: Some application require an explicit user input to proceed. You will not be able to test such component.

Automation: Can be scheduled to run overnight for specific duration, but still require manual input to analyze log and recreate the defect and log into bug tracking system.


Cycle: Overnight, weekly or fortnightly.


Accessibility Testing

For visually Impaired person, Android has talk back features. Which Read loud any UI elements uses touches .Talkback uses content description tag to provide information about an UI element. You can activate Talk Back function from device settings to see if every UI element has Meaningful description . 

Automation: Not possible. Require manual QA input. 

Thursday, September 18, 2014

Install ADB driver for any Android device

You set your device to developer mode from device settings and hoping to see device log on logcat. But that is empty. It is probably because your device is not recognizable by ADB. 

Understand that, device software which help to recognize your device to windows and help you to transfer data is not the ADB driver.


How to install a device manually?
Step 1 [Get the Google USB Driver]
from Android SDK manager install, Google USB driver from extras section.
Step 2 [Find the Device Hardware ID]
  1. Go to your Windows device manager
  2. find your device from the list
  3. then go to its properties.
  4. Select details tab.
  5. Select Hardware ID from drop down.
You will see something like bellow.
USB\VID_18D1&PID_4EE2&REV_0228&MI_00
USB\VID_18D1&PID_4EE2&MI_00
Copy these two line.
Step 3 [Update Your USB Driver]
Go to your device installation folder Under sdk\extras\google\usb_driver you will see a file android_winsub.inf Open the file
Go to Section [Google.NTx86] you will see something like bellow(Do not worry about exact match of device name. ).
;Google Nexus Q
%SingleBootLoaderInterface% = USB_Install, USB\VID_18D1&PID_2C10
%SingleAdbInterface%        = USB_Install, USB\VID_18D1&PID_2C11
Copy this and create a new entry just bellow with your device name. So new entry will look like this,
;My Nexus Q
    %SingleBootLoaderInterface% = USB_Install, [Things you just copied on step 1]
    %SingleAdbInterface%        = USB_Install, [Things you just copied on step 1] 
do the same for section [Google.NTamd64]
Step 4[Installation]
  1. Go to windows Device Manager
  2. Your Device Properties
  3. Driver-> update driver
Show your newly modified android_winsub.inf and install.
Final Step restart you adb.
adb kill-server
adb start-server

Sunday, October 6, 2013

Design Patterns every Android developer should know


Couple of Design pattern i think every android developer should know and understand. I will not try to bore with how to implement each design pattern rather i will try to explain why and where they are necessary on Android platform.

Model-View-Controller

MVC is An architectural design patten help us architect our java classes and resources. MVC make more sense for bigger project.

So, what is the benefit? We can separate our UI code from business logic. Like Leave the Activity for handling all sort of user interaction, save data in data access object, or open network connection on a Network helper class.

For typical application we can architect following way,

View: My XML layouts or resources. My Activity class, Menu and Action bar code.
Controllar: Classes to process my business requirement. Helper or Utility classes can also go this section. 
Model: Classes for storage, caching.

We can even have nested MVC. Think of an app where we are storing user email to a content provider. And, the content provider is a custom content provider we developed for our app. In that case i can sub divide my model code again in MVC style.

View: Data Access Object (DAO)for inserting/retrieving or deleting data. It is also contain every thing needed to initialize my content provider code, like retrieving content resolver or searching through a content provider. This is more close to my business logic, like getMeXData()  
Controller: Code for content provider, like setting up content URI, OR, insert delete.
Model: code to create database or table. Like, SQLiteOpenHelper or BaseColumns code. 

Observer/Observable

Observer observe changes in a another object. And in most cases it is an Observable.
Observable are the object which has been observed by an observer. This patter comes very handy in couple of cases:

Scenario 1, Scanning Access point

When we request a wifi AP scan its take some time to complete the scan and return the result. We can use this design pattern on this purpose. 
Observable: Code for AP scan request. Do some Additional Processing. For example may be we just interested about a specific AP or Signal Strength.
Observer: depend on what we are planning to do once we have to data? We can store the data or draw UI. 

Scenario 2, Location data

Same situation also goes from location data as sometime its take time to retrieve location data.
Observable: Code for location request, like setting up criteria, or checking location accuracy. 
Observer: Update UI or do some thing else depend on business logic. 

Pipeline 

This another design pattern we need when we try to update UI from another thread. Yes i am talking about Handler.

This is very good links explain how pipeline works. http://www.cise.ufl.edu/research/ParallelPatterns/PatternLanguage/AlgorithmStructure/Pipeline.htm

Their are lots of Good example how to use Handler on your Android application so i will not further details on this. But yes we should know what it is and what it does and how it works.

Factory Pattern

Factory is a creational design pattern and help us issue with creating an object. We all probably know how Bitmap factory works on Android. 

Singleton

Singleton prevent us to have multiple instance of an object.

 Then where we need it? Think of the situation where we are creating a cache for storing data. Every-time we update, edit data we do not want multiple instance of data set in that case we will end up with inconsistent data, and changes in one cache object will effect not effect another instance. So, singleton can help you to return current instance, when a instance exist or create a new one if no instance exist. 
 
Android Application Class is also a good example of Singleton pattern.

Adapter Pattern

Adapter pattern help us to translate one interface to a compatible one. Every time we work with a list view we use adapter pattern. Probably it is one of very common design pattern we spends time without probably understanding it. 

Android has bunch of Adapter class. 
  1. List Adapter
  2. Cursor Adapter
  3. Array Adapter
  4. Base Adapter (top level class)

Tuesday, August 13, 2013

Android and Autocomplete


Using Array Adapter

Couple of days ago my boss asked me to add Auto Complete in a search field. Actually he was impressed by seeing Google search bar.





So I start looking into the this issue and find out steps are quite simple.

1. Use AutoCompleteEditTextView
2. Set ArrayAdapter

So just by added following code on Activity onCreate(),
 
private final String[] TEXTS = new String[] {
         "Google Mail", "Google Search", "Google Plus", "Google Finance", "Google Docs", "Google Drive" };
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.auto_complete_tv);
  ArrayAdapter array=new ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, TEXTS);
  textView.setAdapter(array);
 }
And main layout

 


    


This eventually gave me following output



. FYI, 
android.R.layout.simple_dropdown_item_1line is provided by android platform. 


 
    
Custom Array Adapter
 
 Thats a good start but i do not have image on right side. So first thing i need a custom layout to show my custom styled row.

And, my adapter need to understand my new layout that also means that i have to change my ArrayAdapter.

I extend default ArrayAdapter and just update getView method.
  
public class AutoCompleteSimpleArrayAdapter extends ArrayAdapter {
 private final Context mContext;
 private final int layoutId;
 ArrayList data_array;
 public AutoCompleteSimpleArrayAdapter(Context context, int resource, ArrayList objects) {
  super(context, resource, objects);
  // TODO Auto-generated constructor stub
   this.data_array = objects;
      this.mContext=context;
      this.layoutId=resource;
 }
 @Override
    public View getView(int position, View convertView, ViewGroup parent) {
  if (convertView == null) {
   LayoutInflater vi =(LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   convertView = vi.inflate(layoutId, null);
  }
  TextView tv=(TextView)convertView.findViewById(R.id.auto_compete_textView);
  tv.setText(data_array.get(position));
  return convertView;
 }
}
Now a little change in my Activity onCreate to pass my Adapter and layout
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  ArrayList data=new ArrayList();
  data.add("Google Mail");
  data.add("Google Search");
  data.add("Google Plus");
  data.add("Google Finance");
  data.add("Google Docs");
  data.add( "Google Drive");
  AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.auto_complete_tv);
  AutoCompleteSimpleArrayAdapter adapter=new AutoCompleteSimpleArrayAdapter(this, R.layout.simple_image_autocomplete, data);
  textView.setAdapter(adapter);
 }
This gave me following output, which is pretty decent i guess.

Go fancy with layout

But when i was showing this to our designers, she seems not very impressed with one static icon and asked me if we can do little dynamic image and change the images based on the text. And, when start thinking about the problem that seems like whole new issue. I figured out that, in two way i can resolve the issue.
  1.  Change the image on the Adapter Side 
  2.  Pass an Object to the adapter which will contain every single information needed to draw a row.
 Second way seems to be more cleaner approach, as my adapter code will remain will be readable and in that case i just need to update my adapter to understand a custom object which will represent my row information and so i decided to take this route.

This my simple POJO, to represent two images and one text.
 
public class AutoCompleteRow {
 private int logo;
 private String text;
 private int actionImage;
 AutoCompleteRow(int logo, String text, int actionImage){
  this.logo=logo;
  this.text=text;
  this.actionImage=actionImage;
 }
 
 public int getLogo() {
  return logo;
 }
 public void setLogo(int logo) {
  this.logo = logo;
 }
 public String getText() {
  return text;
 }
 public void setText(String text) {
  this.text = text;
 }
 public int getActionImage() {
  return actionImage;
 }
 public void setActionImage(int actionImage) {
  this.actionImage = actionImage;
 }
}
Made new layout name auto_compete_row_items.xml when one image is on left one is on right and text is in next to the left image.
 


 
    
    
    

    

    


Now rewrite my Adapter to take this new change
 
public class AutoCompleteArrayAdapter extends ArrayAdapter {
 protected static final String TAG = AutoCompleteArrayAdapter.class.getSimpleName();
 private final Context mContext;
 private final int layoutId;
 private ArrayList data_array;
 public AutoCompleteArrayAdapter(Context context, int textViewResourceId, ArrayList entries) {
        super(context, textViewResourceId, entries);
        this.data_array = entries;
        this.mContext=context;
        this.layoutId=textViewResourceId;
    }
 public AutoCompleteRow getItem (int position){
  return this.data_array.get(position);
 }
 @Override
    public View getView(int position, View convertView, ViewGroup parent) {
  if (convertView == null) {
   LayoutInflater vi =(LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   convertView = vi.inflate(layoutId, null);
  }
  TextView tv=(TextView)convertView.findViewById(R.id.auto_compete_textView);
  tv.setText(data_array.get(position).getText());
  ImageView logo=(ImageView)convertView.findViewById(R.id.image_view_logo);
  logo.setImageResource(data_array.get(position).getLogo());
  ImageView action=(ImageView)convertView.findViewById(R.id.image_view_action);
  action.setImageResource(data_array.get(position).getActionImage());
  return convertView;
 }
}

Finaly, updated Activity on create
 
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  ArrayList data=new ArrayList();
  data.add(new AutoCompleteRow(R.drawable.google, "Google Mail", R.drawable.gmail));
  data.add(new AutoCompleteRow(R.drawable.google, "Google Plus", R.drawable.google_plus));
  data.add(new AutoCompleteRow(R.drawable.google, "Google Search", R.drawable.search));
  AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.auto_complete_tv);
  AutoCompleteArrayAdapter adapter=new AutoCompleteArrayAdapter(this, R.layout.auto_compete_row_items, data);
  textView.setAdapter(adapter);
 }


Customizing Search Option

When i run this program, i end up with no output. After spending couple of hours trying to debug the issue i realize that, i am using custom object and i have to override getFilter() from my Adapter class. Because AutoCompleteTextView dosnt know how to filter and display text suggestions.  I even customize my filter to show me auto-complete hints if database character contains typed characters instead of typical start with.  After running every thing together i got following output.




if you see the out put, i typed "le", and my auto complete generated all string contains with "le".

This is final Adapter code everything together.


 
public class AutoCompleteArrayAdapter extends ArrayAdapter implements Filterable{
 protected static final String TAG = AutoCompleteArrayAdapter.class.getSimpleName();
 private final Context mContext;
 private final int layoutId;
 private ArrayList data_array;
 public AutoCompleteArrayAdapter(Context context, int textViewResourceId, ArrayList entries) {
        super(context, textViewResourceId, entries);
        this.data_array = entries;
        this.mContext=context;
        this.layoutId=textViewResourceId;
    }
 public AutoCompleteRow getItem (int position){
  return this.data_array.get(position);
 }
 @Override
    public View getView(int position, View convertView, ViewGroup parent) {
  if (convertView == null) {
   LayoutInflater vi =(LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   convertView = vi.inflate(layoutId, null);
  }
  TextView tv=(TextView)convertView.findViewById(R.id.auto_compete_textView);
  tv.setText(data_array.get(position).getText());
  ImageView logo=(ImageView)convertView.findViewById(R.id.image_view_logo);
  logo.setImageResource(data_array.get(position).getLogo());
  ImageView action=(ImageView)convertView.findViewById(R.id.image_view_action);
  action.setImageResource(data_array.get(position).getActionImage());
  return convertView;
 }
  @Override
  public Filter getFilter() {
     return myFilter;
 }
  
  Filter myFilter = new Filter() {
         @Override
         protected FilterResults performFiltering(CharSequence constraint) {
          FilterResults filterResults = new FilterResults();   
          ArrayList orig_array=new ArrayList();
          
             if(constraint != null && data_array!=null) {
              int length=data_array.size();
              int i=0;
                 while(i) results.values;
           if (results.count > 0) {
            notifyDataSetChanged();
           } else {
               notifyDataSetInvalidated();
           }  
       }
  };
}
Loading data from SQLite Database

Our designer told me yes that is what she wants and . So everything is great, but after couple of days another engineers telling me we have more then thousands String in auto-complete suggestion. This raises new issue that we can not store all these text on the memory anymore. So we have to persist it. But, File base I/O do not seems like a good option that means i have to find a way retrieve those word from SQLite database.

After doing some investigation i came up with following steps to resolve the issue.
  1. Create the database
  2. Insert data into database
  3. Query the database
  4. Create my adapter to show and display data.
  5. Bind things together. 

For creating my database i can use SQLiteOpenHelper.


 
public class AutoCompleteHelper extends SQLiteOpenHelper {
 private static final String TAG = AutoCompleteHelper.class.getSimpleName();
 public static final String PRODUCT_TABLE = "_product";
 public static final int DB_VERSION = 1;
 private static final String DATABASE_NAME = " auto_complete.db";
 public AutoCompleteHelper(Context context) {
  super(context, DATABASE_NAME, null, DB_VERSION);
 }
 public Cursor query(SQLiteDatabase db, String query) {
  Cursor cursor = db.rawQuery(query, null);
  return cursor;
 }

 @Override
 public void onCreate(SQLiteDatabase db) {
  // TODO Auto-generated method stub
  final String create_sql_product=String.format("CREATE TABLE %s (" +
    " %s INTEGER PRIMARY KEY AUTOINCREMENT," +
    " %s CHAR(255));", PRODUCT_TABLE, ProductsTable._ID, ProductsTable.MODEL);
  db.execSQL(create_sql_product);
 }
 @Override
 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  // TODO Auto-generated method stub
  db.execSQL(String.format("DROP TABLE IF EXISTS %s", PRODUCT_TABLE));
  this.onCreate(db);
 }
 public static class ProductsTable implements BaseColumns{
  public static final String MODEL="_model";
 }
}

I am implementing base columns to avoid creating required android fields by my self. Other then that table contain only one _model fields.

So far everything is ok. But i have couple of issue.

  1. If i am inserting data on database in Activty onCreate() method i can not insert new data, every time my activity gets created. That means i need a way to resolve this. 
  2. I also have to do regular Query and return cursor (Reason we will see later). 

For resolving both problems, i have created another abstraction which is my Data Access Object (DAO) layer. That means when ever i need data i will ask to DAO and DAO will talk with Database directly.


 
public class AutoCompleteDAO {
 private final Context mContext;
 private static final String[] DATA = new String[] {
   "Google Mail", "Google Search", "Google Plus", "Google Finance", "Google Docs", "Google Drive" };
 private final AutoCompleteHelper mDataBaseHelper;
 
 public AutoCompleteDAO(Context context){
  mContext=context;
  mDataBaseHelper=new AutoCompleteHelper(mContext);
  if (!isDataExist()) 
   addToDatabase(DATA);
 }
 
 public boolean isDataExist(){
  SQLiteDatabase database=mDataBaseHelper.getReadableDatabase();
  long rows;
  SQLiteStatement s = database.compileStatement("select count(*) from _product;");
  try{
   rows= s.simpleQueryForLong();
  }catch(Exception e){
   e.printStackTrace();
   return false;
  }
  return (rows>0) ? true:false; 
 }
 
 public Cursor getAllData() {
        String selectQuery = "SELECT  * FROM _product";
        SQLiteDatabase db = mDataBaseHelper.getReadableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);
        return cursor;
    }
 
 public Cursor getModelCursor(CharSequence args){
  SQLiteDatabase database=mDataBaseHelper.getReadableDatabase();
  String sqlQuery = "";
  Cursor result = null;
  sqlQuery  = " SELECT _id, _model";
  sqlQuery += " FROM "+AutoCompleteHelper.PRODUCT_TABLE;
  sqlQuery += " WHERE _model LIKE '%" + args + "%' ";
  sqlQuery += " ORDER BY _model;";
  result=database.rawQuery(sqlQuery, null);
  return result;
 }
 
 public void addToDatabase(String name){
  ContentValues values = new ContentValues();
        values.put(ProductsTable.MODEL, name);
  SQLiteDatabase database=mDataBaseHelper.getWritableDatabase();
  database.beginTransaction();
  database.insert(AutoCompleteHelper.PRODUCT_TABLE, null, values);
  database.setTransactionSuccessful();
  database.endTransaction();
  database.close();
 }
 
 public boolean addToDatabase(String... models){
  ContentValues values = new ContentValues();
  SQLiteDatabase database=mDataBaseHelper.getWritableDatabase();
  database.beginTransaction();
  try{
   for (String model:models){
    values.put(ProductsTable.MODEL, model);
    database.insert(AutoCompleteHelper.PRODUCT_TABLE, null, values);
   }
   database.setTransactionSuccessful();
  }catch (SQLException e) {
   return false;
  } finally {
   database.endTransaction();
   database.close();
  }
  return true;
 }
}


Couple of things in here

addToDatabase: for inserting data into database i created this overloaded method to insert one single item or arrays.

getModelCursor(CharSequence seq): This method take a String parameter and Query the database and return whatever the data matches parameter string.  You will probably already notice, my query string contains LIKE '%" .

getAllData: It simply returrn result set of all data.

isDataExist(): this where i am checking how many row i have in my database. I decided to do this way it is because i thought i might add more tables in my database.


Now i have everything i need to create my adapter

 
public class AutoCompeteAdapter extends CursorAdapter {
 private static final String TAG=AutoCompeteAdapter.class.getSimpleName();
 private final Context mContext;
 private AutoCompleteDAO dataBaseHelper;
 
 public AutoCompeteAdapter(Context context, Cursor cursor,
   boolean autoRequery) {
  super(context, cursor, autoRequery);
  mContext=context;
  dataBaseHelper=new AutoCompleteDAO(context);
 }

 @Override
 public void bindView(View view, Context context, Cursor cursor) {
  // TODO Auto-generated method stub
  TextView tv=(TextView)view.findViewById(R.id.auto_compete_textView);
  String text=cursor.getString(1);
  tv.setText(text);
 }

 @Override
 public View newView(Context context, Cursor cursor, ViewGroup arg2) {
  // TODO Auto-generated method stub
  LayoutInflater vi =(LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  View convertView = vi.inflate(R.layout.simple_image_autocomplete, null);
  return convertView;
 }
 
 @Override
    public Cursor runQueryOnBackgroundThread(CharSequence constraint){
  Cursor cursor = dataBaseHelper.getModelCursor(constraint);
  return cursor;
    }
 
 @Override
 public String convertToString(Cursor cursor) {
     return cursor.getString(cursor.getColumnIndex(ProductsTable.MODEL));
 }
}

convertToString: This function is needed when we select an auto-complete item from the drop down. Otherwise auto complete text will filled with cursor objects toString() method.
runQueryOnBackgroundThread: As this is a non UI thread function i am just making sure what query will run and what will be returned is implemented in the DAO.
newView: is for creating the view for the first time. I am using one of my layout i used earlier. Important things to notice here is, i do not have to check if convert view is null as it is done by the system and i have bindView method on cursor adapter.

my layout is simple_image_auto_complete.xml


    

    

    


My on create now look like this,

And, finally when i run everything together, i got following output.

 
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.auto_complete_tv);
  Cursor cursor=new AutoCompleteDAO(this).getAllData();
  AutoCompeteAdapter adapter=new AutoCompeteAdapter(this,cursor , true);
  textView.setAdapter(adapter);
 }




Voilla!!!!









Wednesday, August 31, 2011

Top Security weaknesses of android applications

Since start working in mobile space I find out that many developers do mistake when it comes to secure data properly. Many people who have very good security awareness take mobile security lightly. Couple of days ago I read an article where author shows how a bank app storing user information as plain-text. Majority of the mobile users consider their phone as a personal item. Developing application for a mobile environment is bit more sensitive and critical compare to PC environment. If an application is not properly designed it will not only reveal very sensitive information of users but also create a situation where your users will be unable to use his phone. So many apps available on market lack basic security features.

Followings are few features form IT security perspective every mobile app developer should concern about. So many of them will not only reveal user information but also drain battery and eventually users will be unable to use their device. These points I think are very important especially when developers are concern about his users’ data safety and privacy.

Battery Exhaustion
Oh! I haven’t told you guys what I like right? I love news. Not that in so details but I prefer listen or read current headlines. For me, day without news is like day without coffee. Anyway, for this reason I downloaded one of news app. Thought, it will be very interesting to read news even before I get up from my bed in early morning. Well, I have a Motorola defy usually my charge stay almost a day. That means around 12 hours. But just after installing that news app, same day my phone battery died at 3 PM. So, I thought maybe I talked too much that day. But after that day it keep happening and it seems like somehow my phone battery life get shorter or some sort of Star Trek power hungry bug start feeding on my phone battery. So I spent couple of hours trying to figure out what this phone is doing so significant that it has to finish its entire power source and I figure out out only thing is different, is that apps. So when I uninstalled that app everything went back to normal.

So what was wrong? What forced me to uninstall that app, I was eager to install earlier. It is not only about me, but also about other users too. Users will not be able to use an app if that one has battery exhaustion issue. Face is very simple; nobody wants to charge their phones two three times a day. So, how to solve this issue? Personally I do not believe there is a single solution for this problem. Combined with multiple solution will give a good result. Main focus should be reduce network communications, CPU executions, and display usages. Following points are useful, for reducing battery consumption.
• Sync only when phone is connected to a charger or a high speed network or both.
• Cache already downloaded items ex images, text.
• Limit number of network thread.
• If you are planning to get a wake lock think twice.
• Careful about services, receivers or other programs designed to run in background and require extensive amount network, display or CPU.
• Write optimized java code. for some advance technique please follow this link

Insecure cryptographic storage
Some of us take software security very tightly. We secure user data with high bit encryption but when it comes to the point of securing cryptographic token we kind of get loose. Ok let’s go back one step, cryptographic storage means the place where we store our authentication token, crypto token or other security information for future communication. For example, after being verified by a web service (Twitter, Payment gateway etc) server will send a cryptographic token and we need that token for all subsequent communication. Based on request type this token can be for short period or for long period. Whatever the life period is we will try to store that token somewhere. This type of error usually happened when proper safeguard is not taken while program store those tokens. Problem here is that, as authentication system is based on that security token and access to that token simply means that access to all information and impersonating someone from another system will not be a big problem. So, how to secure an authenticated token? One good way to resolve this issue is encrypting security token before writing and decrypting them before reading. All communication from device should be encrypted using present days technology. There is nothing called 100% security in IT security but still we have to take proper measure for user safety, security and privacy.

Unsafe handling of user data
User data could be anything, his name, DOB, SSN or any other sensitive information what is important to user. Usually unsafe conditions occur over communication channel or on device.

Most on device unsafe cases are related to storage policy. This type of scenario can be avoided by choosing a safe way to store user data on device. For example on Android, Shard preference is designed to share information between multiple apps. That means those data are basically expose to others. For example getSharedPreferences(int mode) will give you a shared preference to work with. Please, careful about the mode, set the mode to appropriate level based on your requirement. And, again please do not use shared Preference or Content Provider for storing sensitive information. I know, I know they use SQLlite at the back-end. Things are pretty much same when we store information in SQL Lite database as plain text. And, please never ever store sensitive information as plain-text and for god’s sake do not try to decrypt/encrypt a movie file.

On communication, flaws occur over the communication channel. I will not discuss anything about network security coz there are already millions of books articles in market about it and Android issues are pretty much same as others.

Resolving all these entirely may not be possible but at least we can take some measures to make an attacker life bit interesting. If possible pick standard crypto algorithm to safeguard user data. Make sure that data stored as cipher text is not tempered later by a third party program. If you are not very good with encryption decryption system do some clever stuff to hide data. There are so many things you could do besides running a 1000 bit(!!!) encryption algorithm.
1. encoding/decoding
2. Hiding inside an image.
3. Shift characters. if shift value is five ‘A’ will be ‘E’ or ‘B’ will be ‘F’.

External vs. internal storages
External Storages, the one we commonly known is SD card. Is this wrong to store information on external storage? Absolutely not. Moreover, there are some good things about storing information on SD card. Like, if the data is large then there will be always some space to accommodate and if we take entire space it will not create problem for other application or OS. But there is couple of security issues we have to take care when we pick SD card.

  • External storage is usually removable that means it can be plugged into a desktop or laptop. So an attacker will get more flexibility to analyze data.
  • It is not protected by platform and so it is our responsibility to come up with our own protection plan. We need two different type of protection plant one we don’t want someone to read, so encryption, and we have to make sure stored data is not tempered after we wrote them, so a hash like algorithm.
  • When app is removed/uninstalled data is not removed.

On other hand internal storages are safe easy to handle. But.., it is basically a big “BUT” when we talked about internal storage. Internal storages are usually small in size and there are too many things it has to store. For example majority of the apps downloaded on internal storage, CPU uses internal storage for execution. Bad thing is that if apps required space more than few megabytes for data probably it is better to choose available external storage. I remember one case, where I have to deal with a huge database and I was constantly getting low memory warning after copying entire database on internal memory. So think like the scenario when our apps and other hundred apps are in the same space and then app start taking additional spaces. User will figure out something is very wrong and then he will uninstall our app or set the phone to factory settings.

If we want to share data with other third party apps or systems probably better to use internal space. But again everything is a design issue. Another important thing is that internal storage is safeguarded by Android platform and if somehow someone able to bypass this security feature it will be easy for an attacker to access user private data. For example, phone rooting. Lots of information is out there for how to root a phone and it is not so complicated task even.

From IT security perspective internal storage is a good choice. Coz you app will get at least the security features provided by framework. So I say try to pick internal space but again try to be on your own.

String literal
What’s bad with string constant? Think about the case where bank sent us an ATM card and PIN on same package. It is like encrypting something and later sending cipher text and password at the same package. Basically, it is very easy to retrieve original text, from binary by using a decompiler. There is lots of decompiler existing for android and they are getting better every single day.
Check out the following Android code later its decompilation output. I used apktool for this.

public class hello extends Activity {
/** Called when the activity is first created. */
static final String str1="This is static final String";
final String str2="This is only final string";
String str3="This is only string";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String str3="This is internal string";

}
}

So when I use that decompiler I got the following output.

package com.test.blog; class hello {/*
.class public Lcom/test/blog/hello;
.super Landroid/app/Activity;
.source "hello.java"
# static fields
.field static final str1:Ljava/lang/String; = "This is static final String"
# instance fields
.field final str2:Ljava/lang/String;
.field str3:Ljava/lang/String;
# direct methods
.method public constructor ()V
.locals 1
.prologue
.line 6
invoke-direct {p0}, Landroid/app/Activity;->()V
.line 9
#p0=(Reference);
const-string v0, "This is only final string"
#v0=(Reference);
iput-object v0, p0, Lcom/test/blog/hello;->str2:Ljava/lang/String;
.line 10
const-string v0, "This is only string"
iput-object v0, p0, Lcom/test/blog/hello;->str3:Ljava/lang/String;
.line 6
return-void
.end method
# virtual methods
.method public onCreate(Landroid/os/Bundle;)V
.locals 2
.parameter "savedInstanceState"
.prologue
.line 13
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
.line 14
const/high16 v1, 0x7f03
#v1=(Integer);
invoke-virtual {p0, v1}, Lcom/test/blog/hello;->setContentView(I)V
.line 15
const-string v0, "This is internal string"
.line 17
.local v0, str3:Ljava/lang/String;
#v0=(Reference);
return-void
.end method
*/}

if we take a close look we will see all string literals basically easily readable after decompiling. This is not bad as long as we do not hard code our password on the source file. Consider like this, one dumb developer receive authentication token from a site and after being verified by server, he encrypted his token using 256 bit AES . So whenever he is writing that encrypted token, he is basically encrypting and decrypting using same password or I would say same string literal. Ok forget now about user’s token think of encrypting users’ sensitive information with a hard coded password.
Oh!, information is still retrievable by a decompiler if we put the string on an Android resource file (string). Code obfuscator is good way to handle it but not a guaranteed way.

At the end, it is also very important that where ever we store information we secure sensitive data. By the way Android has a crpto engine which supports so many different crypto algorithms and if we want more variety of crypto algorithms this link will come real handy.