Monday, 27 January 2014

Simulation of Injecting Multi Touch Event in Android

Sample Code which explains how a Multi Touch Event could be dispatched if the Device has root permissions.

the PointerCoords[], we have to set the pressure and size to 1, the default values are 0.
For
public static MotionEvent obtain (long downTime, long eventTime, int action,
         float x, float y, int metaState)

     Create a new MotionEvent, filling in a subset of the basic motion values. 
    Those not specified here are: device id (always 0), pressure and size (always 1), 
x and y precision (always 1), and edgeFlags (always 0).

since the default pressure and size are 1, so we don't need to set them.
Tips for creating gestures:
1. following the real gesture sequence, since we want to simulate the real gestures
  • override the onTouchEvent() to check the real events received by application. These events can also be used for comparison of real user touch events and generated touch events Take browser for example:
    a) @Override public boolean onTouchEvent(MotionEvent event) { Log.i("WebView", event.toString() + event.getAction()); boolean rt = super.onTouchEvent(event); return rt; }
  • manually touch screen to get the real gesture sequence from onTouchEvent() in a). We can follow the event sequence when generating events. -- If we don’t follow the gesture event sequence, the instrumented events may be rejected.
  • Here is a valid event sequence of zoom gesture, (the downTime is the same for all the events)
    i. ACTION_DOWN of one start point
    ii. ACTION_POINTER_2_DOWN of two start points
    iii.ACTION_MOVE of two middle points
    iv. ACTION_POINTER_2_UP of two end points
    v. ACTION_UP of one end point
2. use the API MotionEvent.obtain correctly
  • There are two most used obtain() API.
public static MotionEvent obtain (long downTime, long eventTime, int action, float x, float y, int metaState)
AND
public static MotionEvent obtain(long, long, int, int, android.view.MotionEvent.PointerProperties[], android.view.MotionEvent.PointerCoords[], int, int, float, float, int, int, int, int)
The first one is usually used for single point gestures, like fling, scroll, click etc. The parameters (pressure, size, xPresion, yPresion) for this function are all set to 1.
And the second one is a more general one, and can be used for multi-touch events generation. While for the second one, we have to set the pressure, size in pointerCoords of each touch point to 1.
Here is the example to generate the zoom gesture:
public static void generateZoomGesture(Instrumentation inst,
        long startTime, boolean ifMove, GestureInfo.Point startPoint1,
        GestureInfo.Point startPoint2, GestureInfo.Point endPoint1,
        GestureInfo.Point endPoint2, int duration) {

    if (inst == null || startPoint1 == null
            || (ifMove && endPoint1 == null)) {
        return;
    }

    long eventTime = startTime;
    long downTime = startTime;
    MotionEvent event;
    float eventX1, eventY1, eventX2, eventY2;

    eventX1 = startPoint1.x;
    eventY1 = startPoint1.y;
    eventX2 = startPoint2.x;
    eventY2 = startPoint2.y;

    // specify the property for the two touch points
    PointerProperties[] properties = new PointerProperties[2];
    PointerProperties pp1 = new PointerProperties();
    pp1.id = 0;
    pp1.toolType = MotionEvent.TOOL_TYPE_FINGER;
    PointerProperties pp2 = new PointerProperties();
    pp2.id = 1;
    pp2.toolType = MotionEvent.TOOL_TYPE_FINGER;

    properties[0] = pp1;
    properties[1] = pp2;

    //specify the coordinations of the two touch points
    //NOTE: you MUST set the pressure and size value, or it doesn't work
    PointerCoords[] pointerCoords = new PointerCoords[2];
    PointerCoords pc1 = new PointerCoords();
    pc1.x = eventX1;
    pc1.y = eventY1;
    pc1.pressure = 1;
    pc1.size = 1;
    PointerCoords pc2 = new PointerCoords();
    pc2.x = eventX2;
    pc2.y = eventY2;
    pc2.pressure = 1;
    pc2.size = 1;
    pointerCoords[0] = pc1;
    pointerCoords[1] = pc2;

    //////////////////////////////////////////////////////////////
    // events sequence of zoom gesture
    // 1. send ACTION_DOWN event of one start point
    // 2. send ACTION_POINTER_2_DOWN of two start points
    // 3. send ACTION_MOVE of two middle points
    // 4. repeat step 3 with updated middle points (x,y),
    //      until reach the end points
    // 5. send ACTION_POINTER_2_UP of two end points
    // 6. send ACTION_UP of one end point
    //////////////////////////////////////////////////////////////

    // step 1
    event = MotionEvent.obtain(downTime, eventTime, 
                MotionEvent.ACTION_DOWN, 1, properties, 
                pointerCoords, 0,  0, 1, 1, 0, 0, 0, 0 );

    inst.sendPointerSync(event);

    //step 2
    event = MotionEvent.obtain(downTime, eventTime, 
                MotionEvent.ACTION_POINTER_2_DOWN, 2, 
                properties, pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0);

    inst.sendPointerSync(event);

    //step 3, 4
    if (ifMove) {
        int moveEventNumber = 1;
        moveEventNumber = duration / EVENT_MIN_INTERVAL;

        float stepX1, stepY1, stepX2, stepY2;

        stepX1 = (endPoint1.x - startPoint1.x) / moveEventNumber;
        stepY1 = (endPoint1.y - startPoint1.y) / moveEventNumber;
        stepX2 = (endPoint2.x - startPoint2.x) / moveEventNumber;
        stepY2 = (endPoint2.y - startPoint2.y) / moveEventNumber;

        for (int i = 0; i < moveEventNumber; i++) {
            // update the move events
            eventTime += EVENT_MIN_INTERVAL;
            eventX1 += stepX1;
            eventY1 += stepY1;
            eventX2 += stepX2;
            eventY2 += stepY2;

            pc1.x = eventX1;
            pc1.y = eventY1;
            pc2.x = eventX2;
            pc2.y = eventY2;

            pointerCoords[0] = pc1;
            pointerCoords[1] = pc2;

            event = MotionEvent.obtain(downTime, eventTime,
                        MotionEvent.ACTION_MOVE, 2, properties, 
                        pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0);

            inst.sendPointerSync(event);
        }
    }

    //step 5
    pc1.x = endPoint1.x;
    pc1.y = endPoint1.y;
    pc2.x = endPoint2.x;
    pc2.y = endPoint2.y;
    pointerCoords[0] = pc1;
    pointerCoords[1] = pc2;

    eventTime += EVENT_MIN_INTERVAL;
    event = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_POINTER_2_UP, 2, properties, 
                pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0);
    inst.sendPointerSync(event);

    // step 6
    eventTime += EVENT_MIN_INTERVAL;
    event = MotionEvent.obtain(downTime, eventTime, 
                MotionEvent.ACTION_UP, 1, properties, 
                pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0 );
    inst.sendPointerSync(event);
}

Friday, 17 January 2014

How to Fix Windows 7 Not Genuine Error

In order to fix this problem you’ve to follow the steps mentioned below as it is. Don’t skip any step otherwise the motive will not be achieved. Remember, I’m not going to include any software in order to fix Windows 7 not genuine error.

  1. Start your PC and click on Start button.
  2. Use the search tool over there and search for ‘cmd’.
  3. Right click on the ‘cmd’ in search result and choose option ‘Run as administrator’.
  4. Now type ‘SLMGR –REARM’ and hit enter. Type the words as it is otherwise method will not work.
  5. Now a popup will appear as Windows Script Host which will notify that you’ve successfully completed that command and you need to restart your system.
  6. Follow previous command i.e. restart your PC now.
Fix Windows 7 Not Genuine error
That’s all you need to do to fix Windows 7 not genuine error.
In case you’re still experiencing the same problem then you need to follow below mentioned steps,
  1. Move into your control panel and then go into the Windows Update section. Alternatively you can move into the ‘Uninstall a program’ tool.
  2. Now click on ‘View installed updates’ and wait for all updates to get listed.
  3. Now find out update with name ‘KB971033’ and uninstall it from your Windows.
  4. Restart your PC now.
Hope now the error is fixed on your PC. Don’t forget to share this simple guide on how to fix Windows 7 not genuine error with your friends online.

Wednesday, 25 September 2013

Intentional or Unintentional Unplugging of Ethernet cable or USB cable while on read or recv linux calls

   A very typical scenario when you are coding on a real-time project which requires high stability and sustainability and in the middle someone comes and pulls your ethernet cable or usb cable (in case of mobile devices). At that time your read / recv calls gets blocked and returns after a very long time.

In Linux or Ubuntu, whenever that happens, you should call two functions which would make your read / recv to come out with an error code and they are as follows:
  • shutdown - API of Linux
  • closesocket - API of Linux.

Tuesday, 17 September 2013

Build Project using NDK

Please follow the below guidelines:
  1. Consider the $PROJECT as the Project Directory, say SampleApplication as my Project.
  2. Create two Directories inside the Project Directory, namely
    1. jni\
    2. code\
  3. Place the Android.mk inside the jni\ directory.
  4. Place the entire code inside the code\ directory.
  5. Open command prompt and go to the $Project directory, then run %NDK_BUILD%, provided you are in windows and you have created an Environment Variable named NDK_BUILD which will be as follows: eg: D:\Backups\Android-NDK\ndk-build.
  6. Build the code in windows by giving %NDK_BUILD%.

Sample Android.mk File

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE            :=     libvncclient
LOCAL_SRC_FILES            :=     <source file names, current directory will be jni>
LOCAL_C_INCLUDES        :=  $(LOCAL_PATH)/include/
LOCAL_CFLAGS            :=    <MACRO DEFINITIONS>
LOCAL_LDLIBS            :=   
LOCAL_SHARED_LIBRARIES     :=   
include $(BUILD_SHARED_LIBRARY)

TADA.......................

Sunday, 15 September 2013

Create JNI File from Java Class file

Create a Simple Java Project as given below

package com.example.helloworld;

public class HelloWorldActivity {

    static {
        System.loadLibrary("hello-jni");
    }
   
    public native String stringFromJNI();

}

Compile it. Say the directory is "D:\Project\J2SE Workspace\HelloWorld\bin\classes", then go to this directory where the package starts for the class file, then give

javah com.example.helloworld.HelloWorldActivity

It will create a JNI class for you with the required functions provided in the Java file.

Thursday, 12 September 2013

Install CDT and ADT for Eclipse

Install the choice of Eclipse you need from the eclipse site.

Currently I had Eclipse Keplar

CDT
Use the Repository as below for getting the CDT plugin.
http://download.eclipse.org/tools/cdt/releases/kepler

Use the above repository URL in
Help -> Install New Software
in the Work With text box paste the above URL and press enter, it will search the site for available plugin and install.

ADT

Use the Repository as below for getting the ADT Plugin.
https://dl-ssl.google.com/android/eclipse/

Use the above repository URL in
Help -> Install New Software
in the Work With text box paste the above URL and press enter, it will search the site for available plugin and install.