1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.dumprendertree;
18
19import android.os.Bundle;
20import android.os.Handler;
21import android.os.Message;
22import android.webkit.MockGeolocation;
23import android.webkit.WebStorage;
24
25import java.util.HashMap;
26
27public class CallbackProxy extends Handler implements EventSender, LayoutTestController {
28
29    private EventSender mEventSender;
30    private LayoutTestController mLayoutTestController;
31
32    private static final int EVENT_DOM_LOG = 1;
33    private static final int EVENT_FIRE_KBD = 2;
34    private static final int EVENT_KEY_DOWN_1 = 3;
35    private static final int EVENT_KEY_DOWN_2 = 4;
36    private static final int EVENT_LEAP = 5;
37    private static final int EVENT_MOUSE_CLICK = 6;
38    private static final int EVENT_MOUSE_DOWN = 7;
39    private static final int EVENT_MOUSE_MOVE = 8;
40    private static final int EVENT_MOUSE_UP = 9;
41    private static final int EVENT_TOUCH_START = 10;
42    private static final int EVENT_TOUCH_MOVE = 11;
43    private static final int EVENT_TOUCH_END = 12;
44    private static final int EVENT_TOUCH_CANCEL = 13;
45    private static final int EVENT_ADD_TOUCH_POINT = 14;
46    private static final int EVENT_UPDATE_TOUCH_POINT = 15;
47    private static final int EVENT_RELEASE_TOUCH_POINT = 16;
48    private static final int EVENT_CLEAR_TOUCH_POINTS = 17;
49    private static final int EVENT_CANCEL_TOUCH_POINT = 18;
50    private static final int EVENT_SET_TOUCH_MODIFIER = 19;
51
52    private static final int LAYOUT_CLEAR_LIST = 20;
53    private static final int LAYOUT_DISPLAY = 21;
54    private static final int LAYOUT_DUMP_TEXT = 22;
55    private static final int LAYOUT_DUMP_HISTORY = 23;
56    private static final int LAYOUT_DUMP_CHILD_SCROLL = 24;
57    private static final int LAYOUT_DUMP_EDIT_CB = 25;
58    private static final int LAYOUT_DUMP_SEL_RECT = 26;
59    private static final int LAYOUT_DUMP_TITLE_CHANGES = 27;
60    private static final int LAYOUT_KEEP_WEB_HISTORY = 28;
61    private static final int LAYOUT_NOTIFY_DONE = 29;
62    private static final int LAYOUT_QUEUE_BACK_NAV = 30;
63    private static final int LAYOUT_QUEUE_FWD_NAV = 31;
64    private static final int LAYOUT_QUEUE_LOAD = 32;
65    private static final int LAYOUT_QUEUE_RELOAD = 33;
66    private static final int LAYOUT_QUEUE_SCRIPT = 34;
67    private static final int LAYOUT_REPAINT_HORZ = 35;
68    private static final int LAYOUT_SET_ACCEPT_EDIT = 36;
69    private static final int LAYOUT_MAIN_FIRST_RESP = 37;
70    private static final int LAYOUT_SET_WINDOW_KEY = 38;
71    private static final int LAYOUT_TEST_REPAINT = 39;
72    private static final int LAYOUT_WAIT_UNTIL_DONE = 40;
73    private static final int LAYOUT_DUMP_DATABASE_CALLBACKS = 41;
74    private static final int LAYOUT_SET_CAN_OPEN_WINDOWS = 42;
75    private static final int SET_GEOLOCATION_PERMISSION = 43;
76    private static final int OVERRIDE_PREFERENCE = 44;
77    private static final int LAYOUT_DUMP_CHILD_FRAMES_TEXT = 45;
78    private static final int SET_XSS_AUDITOR_ENABLED = 46;
79
80    CallbackProxy(EventSender eventSender,
81            LayoutTestController layoutTestController) {
82        mEventSender = eventSender;
83        mLayoutTestController = layoutTestController;
84    }
85
86    public void handleMessage(Message msg) {
87        switch (msg.what) {
88        case EVENT_DOM_LOG:
89            mEventSender.enableDOMUIEventLogging(msg.arg1);
90            break;
91        case EVENT_FIRE_KBD:
92            mEventSender.fireKeyboardEventsToElement(msg.arg1);
93            break;
94        case EVENT_KEY_DOWN_1:
95            HashMap map = (HashMap) msg.obj;
96            mEventSender.keyDown((String) map.get("character"),
97                    (String[]) map.get("withModifiers"));
98            break;
99
100        case EVENT_KEY_DOWN_2:
101            mEventSender.keyDown((String)msg.obj);
102            break;
103
104        case EVENT_LEAP:
105            mEventSender.leapForward(msg.arg1);
106            break;
107
108        case EVENT_MOUSE_CLICK:
109            mEventSender.mouseClick();
110            break;
111
112        case EVENT_MOUSE_DOWN:
113            mEventSender.mouseDown();
114            break;
115
116        case EVENT_MOUSE_MOVE:
117            mEventSender.mouseMoveTo(msg.arg1, msg.arg2);
118            break;
119
120        case EVENT_MOUSE_UP:
121            mEventSender.mouseUp();
122            break;
123
124        case EVENT_TOUCH_START:
125            mEventSender.touchStart();
126            break;
127
128        case EVENT_TOUCH_MOVE:
129            mEventSender.touchMove();
130            break;
131
132        case EVENT_TOUCH_END:
133            mEventSender.touchEnd();
134            break;
135
136        case EVENT_TOUCH_CANCEL:
137            mEventSender.touchCancel();
138            break;
139
140        case EVENT_ADD_TOUCH_POINT:
141            mEventSender.addTouchPoint(msg.arg1, msg.arg2);
142            break;
143
144        case EVENT_UPDATE_TOUCH_POINT:
145            Bundle args = (Bundle) msg.obj;
146            int x = args.getInt("x");
147            int y = args.getInt("y");
148            int id = args.getInt("id");
149            mEventSender.updateTouchPoint(id, x, y);
150            break;
151
152        case EVENT_SET_TOUCH_MODIFIER:
153            Bundle modifierArgs = (Bundle) msg.obj;
154            String modifier = modifierArgs.getString("modifier");
155            boolean enabled = modifierArgs.getBoolean("enabled");
156            mEventSender.setTouchModifier(modifier, enabled);
157            break;
158
159        case EVENT_RELEASE_TOUCH_POINT:
160            mEventSender.releaseTouchPoint(msg.arg1);
161            break;
162
163        case EVENT_CLEAR_TOUCH_POINTS:
164            mEventSender.clearTouchPoints();
165            break;
166
167        case EVENT_CANCEL_TOUCH_POINT:
168            mEventSender.cancelTouchPoint(msg.arg1);
169            break;
170
171        case LAYOUT_CLEAR_LIST:
172            mLayoutTestController.clearBackForwardList();
173            break;
174
175        case LAYOUT_DISPLAY:
176            mLayoutTestController.display();
177            break;
178
179        case LAYOUT_DUMP_TEXT:
180            mLayoutTestController.dumpAsText(msg.arg1 == 1);
181            break;
182
183        case LAYOUT_DUMP_CHILD_FRAMES_TEXT:
184            mLayoutTestController.dumpChildFramesAsText();
185            break;
186
187        case LAYOUT_DUMP_HISTORY:
188            mLayoutTestController.dumpBackForwardList();
189            break;
190
191        case LAYOUT_DUMP_CHILD_SCROLL:
192            mLayoutTestController.dumpChildFrameScrollPositions();
193            break;
194
195        case LAYOUT_DUMP_EDIT_CB:
196            mLayoutTestController.dumpEditingCallbacks();
197            break;
198
199        case LAYOUT_DUMP_SEL_RECT:
200            mLayoutTestController.dumpSelectionRect();
201            break;
202
203        case LAYOUT_DUMP_TITLE_CHANGES:
204            mLayoutTestController.dumpTitleChanges();
205            break;
206
207        case LAYOUT_KEEP_WEB_HISTORY:
208            mLayoutTestController.keepWebHistory();
209            break;
210
211        case LAYOUT_NOTIFY_DONE:
212            mLayoutTestController.notifyDone();
213            break;
214
215        case LAYOUT_QUEUE_BACK_NAV:
216            mLayoutTestController.queueBackNavigation(msg.arg1);
217            break;
218
219        case LAYOUT_QUEUE_FWD_NAV:
220            mLayoutTestController.queueForwardNavigation(msg.arg1);
221            break;
222
223        case LAYOUT_QUEUE_LOAD:
224            HashMap<String, String> loadMap =
225                (HashMap<String, String>) msg.obj;
226            mLayoutTestController.queueLoad(loadMap.get("Url"),
227                    loadMap.get("frameTarget"));
228            break;
229
230        case LAYOUT_QUEUE_RELOAD:
231            mLayoutTestController.queueReload();
232            break;
233
234        case LAYOUT_QUEUE_SCRIPT:
235            mLayoutTestController.queueScript((String)msg.obj);
236            break;
237
238        case LAYOUT_REPAINT_HORZ:
239            mLayoutTestController.repaintSweepHorizontally();
240            break;
241
242        case LAYOUT_SET_ACCEPT_EDIT:
243            mLayoutTestController.setAcceptsEditing(
244                    msg.arg1 == 1 ? true : false);
245            break;
246        case LAYOUT_MAIN_FIRST_RESP:
247            mLayoutTestController.setMainFrameIsFirstResponder(
248                    msg.arg1 == 1 ? true : false);
249            break;
250
251        case LAYOUT_SET_WINDOW_KEY:
252            mLayoutTestController.setWindowIsKey(
253                    msg.arg1 == 1 ? true : false);
254            break;
255
256        case LAYOUT_TEST_REPAINT:
257            mLayoutTestController.testRepaint();
258            break;
259
260        case LAYOUT_WAIT_UNTIL_DONE:
261            mLayoutTestController.waitUntilDone();
262            break;
263
264        case LAYOUT_DUMP_DATABASE_CALLBACKS:
265            mLayoutTestController.dumpDatabaseCallbacks();
266            break;
267
268        case LAYOUT_SET_CAN_OPEN_WINDOWS:
269            mLayoutTestController.setCanOpenWindows();
270            break;
271
272        case SET_GEOLOCATION_PERMISSION:
273            mLayoutTestController.setGeolocationPermission(
274                    msg.arg1 == 1 ? true : false);
275            break;
276
277        case OVERRIDE_PREFERENCE:
278            String key = msg.getData().getString("key");
279            boolean value = msg.getData().getBoolean("value");
280            mLayoutTestController.overridePreference(key, value);
281            break;
282
283        case SET_XSS_AUDITOR_ENABLED:
284            mLayoutTestController.setXSSAuditorEnabled(msg.arg1 == 1);
285            break;
286        }
287    }
288
289    // EventSender Methods
290
291    public void enableDOMUIEventLogging(int DOMNode) {
292        obtainMessage(EVENT_DOM_LOG, DOMNode, 0).sendToTarget();
293    }
294
295    public void fireKeyboardEventsToElement(int DOMNode) {
296        obtainMessage(EVENT_FIRE_KBD, DOMNode, 0).sendToTarget();
297    }
298
299    public void keyDown(String character, String[] withModifiers) {
300        // TODO Auto-generated method stub
301        HashMap map = new HashMap();
302        map.put("character", character);
303        map.put("withModifiers", withModifiers);
304        obtainMessage(EVENT_KEY_DOWN_1, map).sendToTarget();
305    }
306
307    public void keyDown(String character) {
308        obtainMessage(EVENT_KEY_DOWN_2, character).sendToTarget();
309    }
310
311    public void leapForward(int milliseconds) {
312        obtainMessage(EVENT_LEAP, milliseconds, 0).sendToTarget();
313    }
314
315    public void mouseClick() {
316        obtainMessage(EVENT_MOUSE_CLICK).sendToTarget();
317    }
318
319    public void mouseDown() {
320        obtainMessage(EVENT_MOUSE_DOWN).sendToTarget();
321    }
322
323    public void mouseMoveTo(int X, int Y) {
324        obtainMessage(EVENT_MOUSE_MOVE, X, Y).sendToTarget();
325    }
326
327    public void mouseUp() {
328        obtainMessage(EVENT_MOUSE_UP).sendToTarget();
329    }
330
331    public void touchStart() {
332        obtainMessage(EVENT_TOUCH_START).sendToTarget();
333    }
334
335    public void addTouchPoint(int x, int y) {
336        obtainMessage(EVENT_ADD_TOUCH_POINT, x, y).sendToTarget();
337    }
338
339    public void updateTouchPoint(int id, int x, int y) {
340        Bundle map = new Bundle();
341        map.putInt("x", x);
342        map.putInt("y", y);
343        map.putInt("id", id);
344        obtainMessage(EVENT_UPDATE_TOUCH_POINT, map).sendToTarget();
345    }
346
347    public void setTouchModifier(String modifier, boolean enabled) {
348        Bundle map = new Bundle();
349        map.putString("modifier", modifier);
350        map.putBoolean("enabled", enabled);
351        obtainMessage(EVENT_SET_TOUCH_MODIFIER, map).sendToTarget();
352    }
353
354    public void touchMove() {
355        obtainMessage(EVENT_TOUCH_MOVE).sendToTarget();
356    }
357
358    public void releaseTouchPoint(int id) {
359        obtainMessage(EVENT_RELEASE_TOUCH_POINT, id, 0).sendToTarget();
360    }
361
362    public void touchEnd() {
363        obtainMessage(EVENT_TOUCH_END).sendToTarget();
364    }
365
366    public void touchCancel() {
367        obtainMessage(EVENT_TOUCH_CANCEL).sendToTarget();
368    }
369
370
371    public void clearTouchPoints() {
372        obtainMessage(EVENT_CLEAR_TOUCH_POINTS).sendToTarget();
373    }
374
375    public void cancelTouchPoint(int id) {
376        obtainMessage(EVENT_CANCEL_TOUCH_POINT, id, 0).sendToTarget();
377    }
378
379    // LayoutTestController Methods
380
381    public void clearBackForwardList() {
382        obtainMessage(LAYOUT_CLEAR_LIST).sendToTarget();
383    }
384
385    public void display() {
386        obtainMessage(LAYOUT_DISPLAY).sendToTarget();
387    }
388
389    public void dumpAsText() {
390        obtainMessage(LAYOUT_DUMP_TEXT, 0).sendToTarget();
391    }
392
393    public void dumpAsText(boolean enablePixelTests) {
394        obtainMessage(LAYOUT_DUMP_TEXT, enablePixelTests ? 1 : 0).sendToTarget();
395    }
396
397    public void dumpChildFramesAsText() {
398        obtainMessage(LAYOUT_DUMP_CHILD_FRAMES_TEXT).sendToTarget();
399    }
400
401    public void dumpBackForwardList() {
402        obtainMessage(LAYOUT_DUMP_HISTORY).sendToTarget();
403    }
404
405    public void dumpChildFrameScrollPositions() {
406        obtainMessage(LAYOUT_DUMP_CHILD_SCROLL).sendToTarget();
407    }
408
409    public void dumpEditingCallbacks() {
410        obtainMessage(LAYOUT_DUMP_EDIT_CB).sendToTarget();
411    }
412
413    public void dumpSelectionRect() {
414        obtainMessage(LAYOUT_DUMP_SEL_RECT).sendToTarget();
415    }
416
417    public void dumpTitleChanges() {
418        obtainMessage(LAYOUT_DUMP_TITLE_CHANGES).sendToTarget();
419    }
420
421    public void keepWebHistory() {
422        obtainMessage(LAYOUT_KEEP_WEB_HISTORY).sendToTarget();
423    }
424
425    public void notifyDone() {
426        obtainMessage(LAYOUT_NOTIFY_DONE).sendToTarget();
427    }
428
429    public void queueBackNavigation(int howfar) {
430        obtainMessage(LAYOUT_QUEUE_BACK_NAV, howfar, 0).sendToTarget();
431    }
432
433    public void queueForwardNavigation(int howfar) {
434        obtainMessage(LAYOUT_QUEUE_FWD_NAV, howfar, 0).sendToTarget();
435    }
436
437    public void queueLoad(String Url, String frameTarget) {
438        HashMap <String, String>map = new HashMap<String, String>();
439        map.put("Url", Url);
440        map.put("frameTarget", frameTarget);
441        obtainMessage(LAYOUT_QUEUE_LOAD, map).sendToTarget();
442    }
443
444    public void queueReload() {
445        obtainMessage(LAYOUT_QUEUE_RELOAD).sendToTarget();
446    }
447
448    public void queueScript(String scriptToRunInCurrentContext) {
449        obtainMessage(LAYOUT_QUEUE_SCRIPT,
450                scriptToRunInCurrentContext).sendToTarget();
451    }
452
453    public void repaintSweepHorizontally() {
454        obtainMessage(LAYOUT_REPAINT_HORZ).sendToTarget();
455    }
456
457    public void setAcceptsEditing(boolean b) {
458        obtainMessage(LAYOUT_SET_ACCEPT_EDIT, b ? 1 : 0, 0).sendToTarget();
459    }
460
461    public void setMainFrameIsFirstResponder(boolean b) {
462        obtainMessage(LAYOUT_MAIN_FIRST_RESP, b ? 1 : 0, 0).sendToTarget();
463    }
464
465    public void setWindowIsKey(boolean b) {
466        obtainMessage(LAYOUT_SET_WINDOW_KEY, b ? 1 : 0, 0).sendToTarget();
467    }
468
469    public void testRepaint() {
470        obtainMessage(LAYOUT_TEST_REPAINT).sendToTarget();
471    }
472
473    public void waitUntilDone() {
474        obtainMessage(LAYOUT_WAIT_UNTIL_DONE).sendToTarget();
475    }
476
477    public void dumpDatabaseCallbacks() {
478        obtainMessage(LAYOUT_DUMP_DATABASE_CALLBACKS).sendToTarget();
479    }
480
481    public void clearAllDatabases() {
482        WebStorage.getInstance().deleteAllData();
483    }
484
485    public void setDatabaseQuota(long quota) {
486        WebStorage.getInstance().setQuotaForOrigin("file://", quota);
487    }
488
489    public void setAppCacheMaximumSize(long size) {
490        WebStorage.getInstance().setAppCacheMaximumSize(size);
491    }
492
493    public void setCanOpenWindows() {
494        obtainMessage(LAYOUT_SET_CAN_OPEN_WINDOWS).sendToTarget();
495    }
496
497    public void setMockGeolocationPosition(double latitude,
498                                           double longitude,
499                                           double accuracy) {
500        MockGeolocation.getInstance().setPosition(latitude,
501                                                  longitude,
502                                                  accuracy);
503    }
504
505    public void setMockGeolocationError(int code, String message) {
506        MockGeolocation.getInstance().setError(code, message);
507    }
508
509    public void setGeolocationPermission(boolean allow) {
510        obtainMessage(SET_GEOLOCATION_PERMISSION, allow ? 1 : 0, 0).sendToTarget();
511    }
512
513    public void setMockDeviceOrientation(boolean canProvideAlpha, double alpha,
514            boolean canProvideBeta, double beta, boolean canProvideGamma, double gamma) {
515        // Configuration is in WebKit, so stay on WebCore thread, but go via the TestShellActivity
516        // as we need access to the Webview.
517        mLayoutTestController.setMockDeviceOrientation(canProvideAlpha, alpha, canProvideBeta, beta,
518                canProvideGamma, gamma);
519    }
520
521    public void overridePreference(String key, boolean value) {
522        Message message = obtainMessage(OVERRIDE_PREFERENCE);
523        message.getData().putString("key", key);
524        message.getData().putBoolean("value", value);
525        message.sendToTarget();
526    }
527
528    public void setXSSAuditorEnabled(boolean flag) {
529        obtainMessage(SET_XSS_AUDITOR_ENABLED, flag ? 1 : 0, 0).sendToTarget();
530    }
531}
532