원본 링크 : http://yuuxxxx.hatenablog.com/entry/2013/09/20/224801

 참조 링크 : http://jo.centis1504.net/?p=1535


 

1
2
3
4
5
6
7
8
9
10
var linkElement=document.getElementById('link');
if/*@cc_on ! @*/ false ) {
    // IE
    linkElement.fireEvent("onclick");
else {
    // Others
    var event = document.createEvent("MouseEvents");
    event.initEvent("click"falsetrue);
    linkElement.dispatchEvent(event);
}
cs


 구글 포토스를 사용하면서 불편한 것이 올렸을때, 자동으로 삭제되어야 되는 경우와 구글 드라이브를 이용해서 사용한다고 해도 paperbak이라는 것의 자체가 대량의 파일이 발생하기 때문에 문제가 된다.


 그래서 javascript를 이용한 자동장치가 필요할 것 같아서 이렇게 기록을 한다.


 document.createEvent라는 것으로 이벤트를 발생시킨다.


 문서 링크 : https://developer.mozilla.org/ko/docs/Web/API/Document/createEvent


 createEvent("MouseEvents") 라는 것 자체가 마우스에 이벤트를 일으키는 용도로 쓰인다.


 다양한 이벤트가 있는데, KeyBoardEvent도 있다.


 initEvent라는 것은 이벤트의 종류를 정의하는 것이다.


 click이벤트를 가지고 있다는 것으로, 그외 자세한건 문서 링크를 참조하면 될 것이다.


 이것은 Click이벤트를 발생시키는 것으고, click말고 mouseup등 마우스의 이벤트 전체를 가지고 있다.

Posted by JunkMam
,

 sameAs라는 메소드가 있고, 그것을 구현하는 내용을 한번 작성해봤다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import java.awt.image.BufferedImage;
 
import com.android.chimpchat.adb.AdbBackend;
import com.android.chimpchat.core.IChimpDevice;
import com.android.chimpchat.core.IChimpImage;
 
import com.android.chimpchat.adb.AdbChimpDevice;
 
import com.android.chimpchat.core.ChimpImageBase;
 
public class MonkeyTest {
    public static void main(String[] args) {
        
        IChimpDevice device = null;
        
        try
        {
            // sdk/platform-tools has to be in PATH env variable in order to find adb
            device = new AdbBackend().waitForConnection();            
        }
        catch(java.lang.NullPointerException e)
        {
            System.out.println("Error");
            System.exit(-1);
        }
        
        // Print Device Name
        System.out.println(device.getProperty("build.model"));
 
        // Take a snapshot and save to out.png
        //device.takeSnapshot().writeToFile("out.png", "png");
        
        IChimpImage deviceImage = device.takeSnapshot();
        deviceImage.writeToFile("out_1.png""png");
        IChimpImage fileImage = ChimpImageBase.loadImageFromFile("out.png");
        fileImage.writeToFile("out_2.png""png");
        
        sameAs(fileImage,deviceImage,0.9);
        
        if(fileImage.sameAs(deviceImage, 0.75))
        {
            System.out.println("Sames");
        }
        else
        {
            System.out.println("Not");
        }
 
        device.dispose();
        
        System.exit(0);
    }
    
    public static boolean sameAs(IChimpImage other, IChimpImage sames, double percent){
        
        BufferedImage otherImage = other.getBufferedImage();
        BufferedImage samesImage = sames.getBufferedImage();
        
        //Easy size check
        if(otherImage.getWidth()!= samesImage.getWidth()){
            return false;
        }
        
        if(otherImage.getHeight()!=samesImage.getHeight()){
            return false;
        }
        
        int[] otherPixel = new int[1];
        int[] samesPixel = new int[1];
        
        int width = samesImage.getWidth();
        int height = samesImage.getHeight();
        
        int numDiffPixels = 0;
        // Now, go through pixel-by-pixel and check that the images are the same;
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                if (samesImage.getRGB(x, y) != otherImage.getRGB(x, y)) {
                    System.out.println(samesImage.getRGB(x, y)+":"+otherImage.getRGB(x, y));
                    numDiffPixels++;
                }
            }
        }
        double numberPixels = (height * width);
        double diffPercent = numDiffPixels / numberPixels;
        
        return percent <= 1.0 - diffPercent;
    }
}
cs



 하지만, 왜 차이가 생기는지는 잘 모르겠다.


 값이 동일하게 나온 것이라고 생각하는데...


 일단, 이렇게 구현을 할 수 있다면, 특정 위치를 조작해서 처리할 수 있는 방법도 만들 수 있다.

Posted by JunkMam
,

 MonkeyRunner를 Java에 연결해서 사용이 가능하다. 라는 식으로 예제 소스와 내용을 설명해주었다.


 이것을 제대로 Java의 소스를 작성하는 방법을 포스팅 할려고 한다.


 먼저, Eclipse을 이용해서 Java Project을 만들어 놓는다.



 프로젝트에서 Properties(환경 설정)에 들어가서 환경을 설정하는 창을 띄운다.



 여기서 Java Build Path(Java에서 Library등을 가지고오게하는 설정이다.)에서 들어가면, Library을 설정할 수 있는 탭이 있다.(이미 추가를 시킨 상태이다.)


 여기서 [Android SDK 경로]\tools\lib\MonkeyRunner.jar 을 가지고온다.


 여기서 MonkeyRunner라는 것은 공개 소스로 제작되어 있는 부분이 있다.(그리고 MonkeyRunner가 아닌, chimpchat.jar을 가지고와서 사용하는게 더 올바른 방식이다.


 MonkeyRunner는 Java + Python인 상태이기 때문에, Python의 정보를 가지고 있지 않는다면, 사용을 제대로 할 수 없는 것을 알 수 있다.

 하지만, MonkeyRunner에서 있는 Python을 분석해서 chimpchar에게 정보를 보내는것을 알 수 있기 때문에, 다음 링크를 읽으면서 분석하면, 이해에 도움이 될 것이다.


 링크 : https://android.googlesource.com/platform/tools/swt/+/android-4.4_r1.1/monkeyrunner/src/main/java/com/android/monkeyrunner


 이제, 다음과 같은 소스를 보여주면서, 자세하게 설명을 하도록 하겠다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import com.android.chimpchat.adb.AdbBackend;
import com.android.chimpchat.core.IChimpDevice;
import com.android.chimpchat.core.IChimpImage;
 
public class MonkeyTest {
    public static void main(String[] args) {
        IChimpDevice device = null;
        try
        {
            // sdk/platform-tools has to be in PATH env variable in order to find adb
            device = new AdbBackend().waitForConnection();            
        }
        catch(java.lang.NullPointerException e)
        {
            System.out.printf("Error");
            System.exit(-1);
        }
 
        // Print Device Name
        System.out.println(device.getProperty("build.model"));
 
        // Take a snapshot and save to out.png
        device.takeSnapshot().writeToFile("out.png""png");
 
        device.dispose();
        
        System.exit(0);
    }
}
cs


 이것에서 device라는 것은 ChimpDevice라는 것으로, Adb에 연결하는 방식으로,


 Python에서 있는 MonkeyDevice와 비슷하다고 보면, 이해가 될 것이다.


 MonkeyRunner는 AdbBackend라는 클래스와 동일하다고 보면 될 것이다.


 AdbBackend라는 클래스는 ADB와 연결되서 통신하는 클래스이다.


 여기서, waitForConnection은 2가지의 함수가 존재하는데.


 waitForConnection()과 waitForConnection(String)이 있다.


 여기서 String에는 ADB에서 있는 Device의 명칭을 작성하면, 해당 Device을 연결 할 수 있게 된다.


 여기서 device의 정보를 얻기 위해서는 ddmuilib이라는 것을 이용해야된다.


 거기에 대해서는 또 다른 방법을 찾아야 될 것이므로, 나중에 하도록 한다.


 Adb의 정보가 없다면, NullPointerException이라는 오류가 발생하는 경우가 있다.

 이 경우에 예외 처리하는게 좋다.


 현재 Device의 명칭을 알기 위해서 device.getProperty을 이용해서 알아보게 만들 수 있으며.


 device.takeSnapshot()을 이용해서 그림을 가지고 올 수 있다.


 writeToFile(String1, String2)에서 String1은 파일 명칭/경로를 뜻하는 것이고, String2는 파일의 포맷이다. 기본적으로 PNG을 기본적으로 가지고 있으며, PNG을 제외한, JPG가 적용이 가능하다.


 device.dispose();는 연결을 끊는 것이다.


 윗 방식을 이용하면, 스샷을 찍어서 png 포맷을 가진 out.png 파일이 생성된다.

Posted by JunkMam
,

 안드로이드 SDK을 업그레이드 혹은 설치하면서 자동으로 설치되는 것이 MonkeyRunner라고 했다.


 이것을 Java에 연결할 수도 있는데, 그 이유는 jar로 MonkeyRunner을 설정해놓았기 때문이다.


 MonkeyRunner는 python와 Java을 같이 연결해서 사용하는 방식으로 Jython이라는 것이다.


 그래서 MonkeyRunner.bat을 이용해서 Python으로 구성한 소스를 동작 시킬 수 있게 할 수 있다.


 Java을 MonkeyRunner로 연결하기 위해서 다음 링크를 보면 도움이 될 것이다.


 링크 : http://stackoverflow.com/questions/6686085/how-can-i-make-a-java-app-using-the-monkeyrunner-api


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import com.android.chimpchat.adb.AdbBackend;
import com.android.chimpchat.core.IChimpDevice;
 
public class MonkeyTest {
    public static void main(String[] args) {
        // sdk/platform-tools has to be in PATH env variable in order to find adb
        IChimpDevice device = new AdbBackend().waitForConnection();
 
        // Print Device Name
        System.out.println(device.getProperty("build.model"));
 
        // Take a snapshot and save to out.png
        device.takeSnapshot().writeToFile("out.png"null);
 
        device.dispose();
    }
}
cs


 윗 예시 소스는 윗 링크에서 가지고온 소스이다.


 여기서, MonkeyRunner가 아닌, MonkeyDevice라는 게 있다.


 원래, MonkeyRunner라는 것은 ADB을 연결해서 처리해주는 중간자 역할을 하는 클래스다.


 그래서 MonkeyRunner을 사용해도 되고, adb을 바로 연결하는 AdbBackend라는 녀석을 사용해도 된다.


 나머지는 MonkeyRunner의 예시와 유사하다.


 단, 연결을 끊고 다시 연결하는 행위를 할 수 있다.(MonkeyRunner는 Python을 다 읽고 난 후에 알아서 종료하게 된다.)


Posted by JunkMam
,

 안드로이드에서 MonkeyRunner라는 것을 알고 있는가?


 안드로이드의 어플을 테스트하기 위해서 사용하는 것으로 python을 이용해서 사용하는 테스트 도구이다.


 안드로이드 스튜디오를 설치하면, ADB로 업그레이드 할때, 같이 설치할 수 있는 도구로써, 구글에서 지원해주는 도구이다.


 ADB와 차이나는 것은 ADB에서는 실행 시킬려면 작업이 많이 드는 이미지 매칭 함수가 들어가 있어. 자동화하기에는 매우 좋은 프로그램이라고 할 수 있다.


 MonkeyRunner라는 것은 원래 목적은 Monkey(원숭이)가 폰을 만지는 것과 같이 자동으로 막 만지게 하는 것을 사용 설명서(python으로 만들어져있는 스크립트)를 보고 눌러보는 장치. 라고 보면 될 것이다.


 MonkeyRunner의 설명은 안드로이드 스튜디오자체에서 설명을 해주고 있다.


 링크 : https://developer.android.com/studio/test/monkeyrunner/index.html


 원래 취지는 매우 좋은 용도로 사용한 것이다.

 참고로 소스로 그냥 넘겨도 되는 기능이 있는데, 이 부분은 다른 프로그래머가 유튜브에 언급했듯. 나중에 생기는 오작동을 잡기가 매우 어려워 지게 된다.

 그걸 방지하고, 귀찮으면 컴퓨터에게 시키게 만들자.

 테스터를 구하기 힘들면, 컴퓨터에게 넘기자.

 라는 뜻으로 만들어진 도구이다.[이것을 악용하면, 안 좋은 작업으로 사용할 수 있게 되겠지만...]


 컴퓨터에게 시키는 장치. 즉, 매크로인 것이다.


 링크에 들어가면, 알 수 있지만, 기본적으로는 python 언어를 이용해서 만들어지게 되어 있다.


 그리고 해당 소스를 사용해서 디바이스를 자동으로 동작 시키는 것이다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Imports the monkeyrunner modules used by this program
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
 
# Connects to the current device, returning a MonkeyDevice object
device = MonkeyRunner.waitForConnection()
 
# Installs the Android package. Notice that this method returns a boolean, so you can test
# to see if the installation worked.
device.installPackage('myproject/bin/MyApplication.apk')
 
# sets a variable with the package's internal name
package = 'com.example.android.myapplication'
 
# sets a variable with the name of an Activity in the package
activity = 'com.example.android.myapplication.MainActivity'
 
# sets the name of the component to start
runComponent = package + '/' + activity
 
# Runs the component
device.startActivity(component=runComponent)
 
# Presses the Menu button
device.press('KEYCODE_MENU', MonkeyDevice.DOWN_AND_UP)
 
# Takes a screenshot
result = device.takeSnapshot()
 
# Writes the screenshot to a file
result.writeToFile('myproject/shot1.png','png')
cs


 윗 소스는 링크에 있는 예제 소스이다.


 device = MonkeyRunner.waitForConnection()


 이것은 MonkeyRunner라는 클래스(jar로 라이브러리가 있다. 나중에 이 라이브러리를 가지고와서 Java로 다시 구성할 수 있게된다.)에 있는 정적 메소드 waitForConnection()을 이용해서 device에 MonkeyDevice라는 클래스로 만들어져 있는 모바일 디바이스의 정보를 받아들인다.(연결 될 때까지 계속 기다리는 동기화된 함수이다.)


 이렇게  구해진 dveice라는 변수에게 계속 명령을 주는 형태이다.


 device.installPackage라는 것은 해당 APK을 해당 모바일에 설치하도록 명령을 넣는 것이다.


 device.startActivity라는 것은 설정되어 있는 어플을 실행시키는 것이며, press/touch등 동작까지 명령으로 설정할 수 있게 된다.


 takeSnapshot()이라는 것으로 이미지를 메모리에 불러올 수 있게 되며, writeToFile을 이용해서 파일을 입력하도록 할 수 있고, 파일을 읽어 들여서 매칭 시킬 수도 있다.

Posted by JunkMam
,

 ADB로 Unicode을 입력할 수 있는지 궁금해서 구글링을 하다가 찾은 것이다.

 (ADB로 한글을 입력 할 수 있다!)


 하는 방법은 소스 사이트에 들어가서 APK을 설치한 후(불안하면, 소스만 보고 필요한 부분말 빼가서 처리하면 된다.) 키보드를 설정한 후에 ADB의 브로드 캐스트를 보내주면 된다.


 원리는 APK로 만들어진 가상 키보드가 BroadCastReciver가 존재하고, 이것이 ADB로 보내는 브로드 캐스트를 받는다.

 받은 브로드 캐스트의 내용은 가상 키보드가 내용물로 처리해주는 방식이다.


 키보드 기본 설정을 해야되는 불편함만 제외하고, 이걸 이용하면, ADB가 사용하는 BroadCast을 이용해서 UNICODE을 송신을 받아서 자동으로 입력을 받을 수 있게 해준다.


 ADB로 키보드를 변경하는 방법도 적혀져 있다.


 한자, 한글, 영어 전부다 지원이 되는 걸 확인 했지만, 문제는 스페이스가 지원이 안된다.


 아마도 브로드 캐스트라서 그런 것 같다.


 소스가 있으니, 특정 기호 = 스페이스바. 이렇게 수정이 가능할 것이다.


 소스


 관련 질문 사이트

Posted by JunkMam
,

 분석하였을때, swipe과 tap은 분석이 되었으나, 다중 터치에 대해서는 언급이 되어 있지 않았다.


 다중 터치를 처리 하기 위해선 먼저 터치가 시작되었다는 정보를 보내야된다.

 0003 0039 로 터치가 시작되었다는 정보가 일어난 후에

 tap이나 swipe과 동일하게, 작업을 하는데, 차이점은

 0003 002f 00000000이라는 정보가 종료 지점에서 넣게 된다는 점이다.

 이것은 다중 터치에서 일어난다.


 예을 들어서 다음과 같게 된다.


 0003 002f 00000000

 0003 0039 00000001

 0003 0035 0000000f

 0003 0036 00000001

 0003 0030 00000002

 0003 003a 00000002

 0000 0000 00000000


 이렇게가 바로 하나의 터치 인식이라는 것이다.

 여기서 다음 터치를 넣기 위해선

 

 0003 002f 00000001

 0003 0039 00000001

 0003 0035 0000000f

 0003 0036 00000001

 0003 0030 00000002

 0003 003a 00000002

 0000 0000 00000000


 이런식으로 인식이 된다는 점이다.


 간단하게 말해서

 002f는 터치의 갯수이고, 0039는 터치의 횟수, 0035 : X축, 0036 : Y축가 되는 것이다.

Posted by JunkMam
,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#if defined(UNICODE) && !defined(_UNICODE)
    #define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
    #define UNICODE
#endif
 
#include <tchar.h>
#include <windows.h>
 
#include <stdio.h>
#include <stdlib.h>
 
#define MAX_LINE 4096
 
/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
 
/*  Make the class name into a global variable  */
TCHAR szClassName[ ] = _T("ADB 연결 장치");
 
//프로세스를 위한 변수
HANDLE write_in, write_out;
HANDLE read_in, read_out;
 
SECURITY_ATTRIBUTES sec;
 
long unsigned int writen=0;
long unsigned int readn=0;
 
int rtv;
 
char command[80= {0,};
char buffer[MAX_LINE];
 
STARTUPINFO si={0,};
PROCESS_INFORMATION pi;
 
int x=0;
int y=0;
 
 
int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */
 
    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);
 
    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
 
    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;
 
    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           szClassName,       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );
 
    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);
 
    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 00))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }
 
    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}
 
 
/*  This function is called by the Windows function DispatchMessage()  */
 
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int i=0;
 
    switch (message)                  /* handle the messages */
    {
        case WM_CREATE:
            sec.nLength=sizeof(SECURITY_ATTRIBUTES);
            sec.bInheritHandle=TRUE;
            sec.lpSecurityDescriptor=NULL;
 
            CreatePipe(&write_out,&write_in,&sec,0);
            CreatePipe(&read_in,&read_out,&sec,0);
 
            sprintf(command,"./adb.exe shell",NULL);
 
            si.cb=sizeof(STARTUPINFO);
            si.hStdInput=write_out;
            si.hStdOutput=read_out;
            si.dwFlags=STARTF_USESTDHANDLES;
 
            rtv=CreateProcess(NULL,
                            command,
                            NULL,
                            NULL,
                            TRUE,
                            NULL,
                            NULL,
                            NULL,
                            &si,
                            &pi);
 
            if(!rtv){
                printf("Error");
                PostQuitMessage (0);
            }
            sprintf(buffer,"sendevent /dev/input/event2 3 57 1\n");
            WriteFile(write_in,buffer,strlen(buffer),&writen,NULL);
            printf("%s",buffer);
 
 
            break;
        case WM_KEYDOWN:
            switch(wParam){
                case VK_UP:
                    y++;
                    x++;
                    sprintf(buffer,"sendevent /dev/input/event2 3 53 50\n",x);
                    WriteFile(write_in,buffer,strlen(buffer),&writen,NULL);
                    printf("%s",buffer);
                    sprintf(buffer,"sendevent /dev/input/event2 3 54 %d\n",y);
                    WriteFile(write_in,buffer,strlen(buffer),&writen,NULL);
                    printf("%s",buffer);
                    sprintf(buffer,"sendevent /dev/input/event2 3 48 2\n");
                    WriteFile(write_in,buffer,strlen(buffer),&writen,NULL);
                    printf("%s",buffer);
                    sprintf(buffer,"sendevent /dev/input/event2 3 58 5\n");
                    WriteFile(write_in,buffer,strlen(buffer),&writen,NULL);
                    printf("%s",buffer);
                    sprintf(buffer,"sendevent /dev/input/event2 0 0 0\n");
                    WriteFile(write_in,buffer,strlen(buffer),&writen,NULL);
                    printf("%s",buffer);
                    /*
                    strcpy(buffer,"sendevent /dev/input/event2 3 57 -1\n");
                    WriteFile(write_in,buffer,strlen(buffer),&writen,NULL);
                    printf("%s",buffer);
                    strcpy(buffer,"sendevent /dev/input/event2 0 0 0\n");
                    WriteFile(write_in,buffer,strlen(buffer),&writen,NULL);
                    printf("%s",buffer);
                    */
                Sleep(250);
                default :
                    printf("%d",wParam);
                    break;
            }
            /*
            for(i=0;i<MAX_LINE;i++){
                buffer[i]=0x00;
            }
            ReadFile(read_in,buffer,sizeof(buffer),&readn,NULL);
            printf("%s",buffer);
            */
            break;
        case WM_DESTROY:
            strcpy(buffer,"exit\n");
            WriteFile(write_in,buffer,strlen(buffer),&writen,NULL);
            printf("%s",buffer);
 
            CloseHandle(write_in);
            CloseHandle(write_out);
            CloseHandle(read_in);
            CloseHandle(read_out);
            CloseHandle(pi.hProcess);
 
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }
 
    return 0;
}
 
 
cs


Posted by JunkMam
,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
0003 002f 00000000//0번째 터치
 
0003 002f 00000001//1번째 터치
 
//sendevent 설정
sendevent /dev/input/event2 0 0 0
 
- tap
0003 0039 00003c4a
0003 0035 00000133
0003 0036 00000154
0003 0030 00000022
0003 003a 00000005
0000 0000 00000000
0003 0039 ffffffff
0000 0000 00000000
 
 
- swipe
0003 0039 00003c4c
0003 0035 0000003a
0003 0036 00000136
0003 0030 00000016
0003 003a 00000002
0000 0000 00000000
0003 0035 00000056
0003 0036 00000120
0003 0030 00000021
0000 0000 00000000
0003 0035 00000066
0003 0036 00000117
0003 003a 00000004
0000 0000 00000000
0003 0035 0000007a
0003 0036 0000010e
0000 0000 00000000
0003 0035 00000088
0003 0036 00000106
0000 0000 00000000
0003 0035 0000009a
0003 0036 000000fe
0003 003a 00000006
0000 0000 00000000
0003 0035 000000a7
0003 0036 000000f9
0003 003a 00000004
0000 0000 00000000
0003 0035 000000bf
0003 0036 000000f2
0003 003a 00000005
0000 0000 00000000
0003 0035 000000ce
0003 0036 000000ef
0003 003a 00000004
0000 0000 00000000
0003 0035 000000dc
0003 0036 000000ec
0000 0000 00000000
0003 0035 000000eb
0003 0036 000000eb
0000 0000 00000000
0003 0035 000000f9
0003 003a 00000003
0000 0000 00000000
0003 0035 0000010c
0003 0036 000000ef
0003 003a 00000004
0000 0000 00000000
0003 0035 0000011c
0003 0036 000000f5
0003 003a 00000006
0000 0000 00000000
0003 0035 0000012a
0003 0036 000000fd
0003 003a 00000005
0000 0000 00000000
0003 0035 00000136
0003 0036 00000105
0003 003a 00000004
0000 0000 00000000
0003 0035 00000140
0003 0036 0000010f
0000 0000 00000000
0003 0035 0000014a
0003 0036 0000011a
0000 0000 00000000
0003 0035 00000153
0003 0036 00000127
0000 0000 00000000
0003 0035 00000158
0003 0036 00000133
0000 0000 00000000
0003 0035 0000015d
0003 0036 00000141
0003 003a 00000005
0000 0000 00000000
0003 0035 00000162
0003 0036 00000153
0003 003a 00000004
0000 0000 00000000
0003 0035 00000163
0003 0036 00000161
0003 003a 00000005
0000 0000 00000000
0003 0035 00000164
0003 0036 00000171
0003 003a 00000004
0000 0000 00000000
0003 0035 00000163
0003 0036 0000017f
0000 0000 00000000
0003 0035 0000015e
0003 0036 00000192
0003 003a 00000003
0000 0000 00000000
0003 0035 00000154
0003 0036 000001a6
0003 003a 00000002
0000 0000 00000000
0003 0035 00000144
0003 0036 000001b5
0003 003a 00000004
0000 0000 00000000
0003 0035 0000012e
0003 0036 000001c9
0000 0000 00000000
0003 0035 00000119
0003 0036 000001d7
0000 0000 00000000
0003 0035 00000103
0003 0036 000001e2
0000 0000 00000000
0003 0035 000000e8
0003 0036 000001f1
0000 0000 00000000
0003 0035 000000d3
0003 0036 000001ff
0003 003a 00000002
0000 0000 00000000
0003 0035 000000bd
0003 0036 00000209
0003 003a 00000004
0000 0000 00000000
0003 0035 000000aa
0003 0036 0000020e
0003 003a 00000002
0000 0000 00000000
0003 0035 000000a1
0003 003a 00000004
0000 0000 00000000
0003 0035 00000090
0003 0036 0000020c
0003 0030 0000000d
0003 003a 00000001
0000 0000 00000000
0003 0039 ffffffff
0000 0000 00000000
 
 
cs


여기서 본다면, 

이벤트는 총 3형태로 입력을 받는다는걸 알 수 있다.

첫번째열인 0003과 0000에서

0003은 터치레 관련된 걸 뜻하는 것 같고,

0000은 시스템적으로 종료를 뜻하는 것 같다.

0039는 터치의 시작을 뜻하는 것인 것 같고

00003c4a와 00003c4c는 터치의 횟수이다.

002f는 터치의 갯수의 종료를 뜻하는 거라고 알 수 있을것이다.

다중 처리 방법으로 처리 할 수 있을 것이다.(ZoomIn/Out)


기본적으로


1
2
3
4
5
6
7
8
9
10
0003 0039 00003c4a // tap 시작
0003 0035 00000133 // x 혹은 y
0003 0036 00000154 // x 혹은 y
0003 0030 00000022 // Prs
0003 003a 00000005 // 
0000 0000 00000000 // 입력
0003 0039 ffffffff // 터치 종료
0000 0000 00000000 // 입력
 
 
cs


이런 형태이고, 이걸 응용하여, 값을 측정 해 낸다.

Hex값이기 때문에, 3c4a같은 건 횟수에서 꽤 많은 터치가 있었다는 뜻이 된다.

0x35는 X축 0x36 Y축의 값을 처리하게 되어있고, 0x30은 Prs의 Size 뜻이다.(면적)

0x3a는 Prs를 뜻하게 된다.

Posted by JunkMam
,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#if defined(UNICODE) && !defined(_UNICODE)
    #define _UNICODE
#elif defined(_UNICODE) && !defined(UNICODE)
    #define UNICODE
#endif
 
#include <tchar.h>
#include <windows.h>
 
#include <stdio.h>
#include <stdlib.h>
 
#define MAX_LINE 4096
 
/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
 
/*  Make the class name into a global variable  */
TCHAR szClassName[ ] = _T("ADB 연결 장치");
 
//프로세스를 위한 변수
HANDLE write_in, write_out;
HANDLE read_in, read_out;
 
SECURITY_ATTRIBUTES sec;
 
long unsigned int writen=0;
long unsigned int readn=0;
 
int rtv;
 
char command[80= {0,};
char buffer[MAX_LINE];
 
STARTUPINFO si={0,};
PROCESS_INFORMATION pi;
 
 
int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */
 
    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);
 
    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
 
    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;
 
    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           szClassName,       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );
 
    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);
 
    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 00))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }
 
    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}
 
 
/*  This function is called by the Windows function DispatchMessage()  */
 
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int i=0;
 
    switch (message)                  /* handle the messages */
    {
        case WM_CREATE:
            sec.nLength=sizeof(SECURITY_ATTRIBUTES);
            sec.bInheritHandle=TRUE;
            sec.lpSecurityDescriptor=NULL;
 
            CreatePipe(&write_out,&write_in,&sec,0);
            CreatePipe(&read_in,&read_out,&sec,0);
 
            sprintf(command,"./adb.exe shell",NULL);
 
            si.cb=sizeof(STARTUPINFO);
            si.hStdInput=write_out;
            si.hStdOutput=read_out;
            si.dwFlags=STARTF_USESTDHANDLES;
 
            rtv=CreateProcess(NULL,
                            command,
                            NULL,
                            NULL,
                            TRUE,
                            NULL,
                            NULL,
                            NULL,
                            &si,
                            &pi);
 
            if(!rtv){
                printf("Error");
                PostQuitMessage (0);
            }
 
            break;
        case WM_KEYDOWN:
            strcpy(buffer,"input keyevent 26\n");
            WriteFile(write_in,buffer,strlen(buffer),&writen,NULL);
            printf("%s",buffer);
 
            for(i=0;i<MAX_LINE;i++){
                buffer[i]=0x00;
            }
 
            ReadFile(read_in,buffer,sizeof(buffer),&readn,NULL);
            printf("%s",buffer);
            break;
        case WM_DESTROY:
            strcpy(buffer,"exit\n");
            WriteFile(write_in,buffer,strlen(buffer),&writen,NULL);
            printf("%s",buffer);
 
            CloseHandle(write_in);
            CloseHandle(write_out);
            CloseHandle(read_in);
            CloseHandle(read_out);
            CloseHandle(pi.hProcess);
 
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }
 
    return 0;
}
 
 
cs


윗 방법을 이용해서 Win32로 GUI을 적용할 수 있게 된다.

여기서, 키보드를 누르면 전원키를 누르는 효과를 가지게 된다.


Timer을 이용해서 ADB의 ScreenCap의 내용을 가지고 오게 할 수도 있다.

Posted by JunkMam
,