1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 package ifc.awt;
25 
26 import com.sun.star.accessibility.AccessibleRole;
27 import com.sun.star.accessibility.XAccessible;
28 import com.sun.star.accessibility.XAccessibleComponent;
29 import com.sun.star.accessibility.XAccessibleContext;
30 import com.sun.star.awt.KeyEvent;
31 import com.sun.star.awt.MouseEvent;
32 import com.sun.star.awt.Point;
33 import com.sun.star.awt.Rectangle;
34 import com.sun.star.awt.XKeyHandler;
35 import com.sun.star.awt.XMouseClickHandler;
36 import com.sun.star.awt.XUserInputInterception;
37 import com.sun.star.awt.XWindow;
38 import com.sun.star.frame.XModel;
39 import com.sun.star.lang.EventObject;
40 import com.sun.star.lang.XMultiServiceFactory;
41 import com.sun.star.uno.UnoRuntime;
42 import java.awt.Robot;
43 import java.awt.event.InputEvent;
44 import lib.MultiMethodTest;
45 import util.AccessibilityTools;
46 
47 /**
48 * Testing <code>com.sun.star.awt.XUserInputInterception</code>
49 * interface methods:
50 * <ul>
51 *  <li><code> addKeyHandler() </code></li>
52 *  <li><code> removeKeyHandler() </code></li>
53 *  <li><code> addMouseClickHandler() </code></li>
54 *  <li><code> removeMouseClickHandler() </code></li>
55 * </ul><p>
56 * This test needs the following object relations :
57 * <ul>
58 *  <li> <code>'XUserInputInterception.XModel'</code> (of type <code>XModel</code>):
59 *   used as model where a mouse click or a key press could be done </li>
60 * </ul> <p>
61 * Test is <b> NOT </b> multithread compilant. <p>
62 * @see com.sun.star.awt.XUserInputInterception
63 */
64 public class _XUserInputInterception extends MultiMethodTest {
65     public XUserInputInterception oObj = null;
66 
67     private XModel m_XModel = null;
68 
69     /** the listener 1 for the mouse click test */
70     private MyMouseClickHandler1 m_MouseListener1 = null;
71     /** the listener 2 for the mouse click test */
72     private MyMouseClickHandler2 m_MouseListener2 = null;
73 
74     /** the listener 1 for the key event test */
75     private MyKeyHandler1 m_KeyListener1 = null;
76     /** the listener 2 for the key event test */
77     private MyKeyHandler2 m_KeyListener2 = null;
78 
79     /** indicates if the mousePressed event was called*/
80     private boolean m_mousePressed1 = false;
81     /** indicates if the mouseReleased event was called*/
82     private boolean m_mouseReleased1 = false;
83 
84     /** indicates if the mousePressed event was called*/
85     private boolean m_mousePressed2 = false;
86     /** indicates if the mouseReleased event was called*/
87     private boolean m_mouseReleased2 = false;
88 
89     /** indicates if the mousePressed event was called*/
90     private boolean m_keyPressed1 = false;
91     /** indicates if the mouseReleased event was called*/
92     private boolean m_keyReleased1 = false;
93 
94     /** indicates if the mousePressed event was called*/
95     private boolean m_keyPressed2 = false;
96     /** indicates if the mouseReleased event was called*/
97     private boolean m_keyReleased2 = false;
98 
99     /** get the object rlation XUserInputInterception.XModel from the
100      * test environment
101      */
before()102     protected void before() {
103         log.print("try to get object relation 'XUserInputInterception.XModel': ");
104         m_XModel = (XModel)tEnv.getObjRelation("XUserInputInterception.XModel");
105         if (m_XModel == null) log.println("failed => null");
106         else log.println("OK");
107 
108     }
109 
110     /**
111     * This test adds two different key listener to the object. <p>
112     *
113     * Has <b> OK </b> if no exception is thrown.
114     */
_addKeyHandler()115     public void _addKeyHandler() {
116 
117         log.println("creating key listener 1");
118         m_KeyListener1 = new MyKeyHandler1();
119 
120         log.println("creating key listener 2");
121         m_KeyListener2 = new MyKeyHandler2();
122 
123 
124         log.println("adding key listener 1");
125         oObj.addKeyHandler(m_KeyListener1);
126 
127 
128         log.println("adding key listener 2");
129         oObj.addKeyHandler(m_KeyListener2);
130 
131         tRes.tested("addKeyHandler()", true);
132     }
133 
134     /**
135      * The test requires <CODE>addKeyHandler()</CODE> which adds two key listener.
136      * Then one of them will be removed. In a second thread a key event is released
137      * by the <CODE>robot</CODE> class.<p>
138      * Has <b> OK </b> status if only one of the listener are triggered. <p>
139      * The following method tests are to be completed successfully before :
140      * <ul>
141      *  <li> <code> addKeyHandler() </code> : adds two key listener </li>
142      * </ul>
143      */
_removeKeyHandler()144     public void _removeKeyHandler() {
145         requiredMethod("addKeyHandler()");
146 
147         log.println("remove key listener 2");
148 
149         oObj.removeKeyHandler(m_KeyListener2);
150 
151         log.println("starting thread to check the key listener...");
152         EventTrigger et = new EventTrigger(m_XModel, EventTriggerType.KEY_TEXT_INTO_DOC);
153 
154         et.run();
155 
156         util.utils.shortWait(tParam.getInt(util.PropertyName.SHORT_WAIT) * 2);
157         log.println("key listener thread should be finished.");
158 
159 
160         boolean bOK = m_keyPressed1 & m_keyReleased1 &
161                       ! m_keyPressed2 & ! m_keyReleased2;
162 
163         if (! bOK){
164             log.println("The key listener has not the expectd status:");
165             log.println("listener\texpected\tgot");
166             log.println("keyPressed1\ttrue\t"+m_keyPressed1);
167             log.println("keyReleased1\ttrue\t"+m_keyReleased1);
168             log.println("keyPressed2\tfalse\t"+m_keyPressed2);
169             log.println("keyReleased2\tfalse\t"+m_keyReleased2);
170         }
171 
172         log.println("remove Key listener 1");
173         oObj.removeKeyHandler(m_KeyListener1);
174 
175         tRes.tested("removeKeyHandler()", bOK);
176     }
177 
178     /**
179      * This test adds two different mouse klick listener to the object. <p>
180      *
181      * Has <b> OK </b> if no exception is thrown.
182      */
_addMouseClickHandler()183     public void _addMouseClickHandler() {
184         log.println("creating mouse listener 1");
185         m_MouseListener1 = new MyMouseClickHandler1();
186         log.println("creating mouse listener 2");
187         m_MouseListener2 = new MyMouseClickHandler2();
188 
189         log.println("adding mouse listener 1");
190         oObj.addMouseClickHandler(m_MouseListener1);
191         log.println("adding mouse listener 2");
192         oObj.addMouseClickHandler(m_MouseListener2);
193 
194         tRes.tested("addMouseClickHandler()", true);
195     }
196 
197     /**
198      *  The test requires <CODE>addMouseClickHandler()</CODE> which adds two key listener.
199      * Then one of them will be removed. In a second thread a mouse klick event is released
200      * by the <CODE>robot</CODE> class.<p>
201      * Has <b> OK </b> status if only one of the listener are triggered. <p>
202      * The following method tests are to be completed successfully before :
203      * <ul>
204      *  <li> <code> addMouseKlickHandler() </code> : adds two key listener </li>
205      * </ul>
206      */
_removeMouseClickHandler()207     public void _removeMouseClickHandler() {
208         requiredMethod("addMouseClickHandler");
209 
210         log.println("remove mouse listener 2");
211 
212         oObj.removeMouseClickHandler(m_MouseListener2);
213 
214         log.println("starting thread to check the mouse listener...");
215         EventTrigger et = new EventTrigger(m_XModel, EventTriggerType.MOUSE_KLICK_INTO_DOC);
216 
217         et.run();
218 
219         util.utils.shortWait(tParam.getInt(util.PropertyName.SHORT_WAIT) * 2);
220         log.println("mouse listener thread should be finished.");
221 
222         boolean bOK = m_mousePressed1 & m_mouseReleased1 &
223                       ! m_mousePressed2 & ! m_mouseReleased2;
224 
225         if (! bOK){
226             log.println("The mouse listener has not the expectd status:");
227             log.println("listener\t\texpected\tgot");
228             log.println("mousePressed1\ttrue\t\t"+m_mousePressed1);
229             log.println("mouseReleased1\ttrue\t\t"+m_mouseReleased1);
230             log.println("mousePressed2\tfalse\t\t"+m_mousePressed2);
231             log.println("mouseReleased2\tfalse\t\t"+m_mouseReleased2);
232         }
233 
234         log.println("remove mouse listener 1");
235         oObj.removeMouseClickHandler(m_MouseListener1);
236 
237         tRes.tested("removeMouseClickHandler()", bOK);
238     }
239 
240 
241     /**
242     * Forces environment recreation.
243     */
after()244     protected void after() {
245         disposeEnvironment();
246     }
247 
248     /**
249      * Listener which added and its method must be called
250      * on <code>keyPressed</code> and <code>keyReleased</code> call.
251      */
252     public class MyKeyHandler1 implements XKeyHandler {
253         /**
254          * This event sets the member <code>m_keyPressed</coed> to
255          *  <code>true</code>
256          * @param oEvent The key event informs about the pressed key.
257          * @return returns <CODE>TRUE</CODE> in erery case
258          */
keyPressed( KeyEvent oEvent )259         public boolean keyPressed( KeyEvent oEvent ){
260             log.println("XKeyHandler 1: keyPressed-Event");
261             m_keyPressed1 = true;
262             return true;
263         }
264         /**
265          * This event sets the member <code>m_keyReleased</coed> to
266          *  <code>true</code>
267          * @param oEvent The key event informs about the pressed key.
268          * @return returns <CODE>TRUE</CODE> in erery case
269          */
keyReleased( KeyEvent oEvent )270         public boolean keyReleased( KeyEvent oEvent ){
271             log.println("XKeyHandler 1: keyReleased-Event");
272             m_keyReleased1 = true;
273             return true;
274         }
275         /**
276          * This event does nothing usefull
277          * @param oEvent refers to the object that fired the event.
278          */
disposing( EventObject oEvent )279         public void disposing( EventObject oEvent ){
280             log.println("XKeyHandler 1: disposing-Event");
281         }
282     }
283     /**
284      * Listener which added and its method must be called
285      * on <code>keyPressed</code> and <code>keyReleased</code> call.
286      */
287     public class MyKeyHandler2 implements XKeyHandler {
288         /**
289          * This event sets the member <code>m_keyPressed</coed> to
290          *  <code>true</code>
291          * @param oEvent The key event informs about the pressed key.
292          * @return returns <CODE>TRUE</CODE> in erery case
293          */
keyPressed( KeyEvent oEvent )294         public boolean keyPressed( KeyEvent oEvent ){
295             log.println("XKeyHandler 2: keyPressed-Event: " +
296                         "This should not be happen because listener is removed!");
297             m_keyPressed2 = true;
298             return true;
299         }
300         /**
301          * This event sets the member <code>m_keyReleased</coed> to
302          *  <code>true</code>
303          * @param oEvent The key event informs about the pressed key.
304          * @return returns <CODE>TRUE</CODE> in erery case
305          */
keyReleased( KeyEvent oEvent )306         public boolean keyReleased( KeyEvent oEvent ){
307             log.println("XKeyHandler 2: keyReleased-Event: " +
308                     "This should not be happen because listener is removed!");
309             m_keyReleased2 = true;
310             return true;
311         }
312         /**
313          * This event does nothing usefull
314          * @param oEvent refers to the object that fired the event.
315          */
disposing( EventObject oEvent )316         public void disposing( EventObject oEvent ){
317             log.println("XKeyHandler 2: disposing-Event: " +
318                         "This should not be happen because listener is removed!");
319         }
320     }
321 
322     /**
323      * Listener which added and its method must be called
324      * on <code>mousePressed</code> and <code>mouseReleased</code> call.
325      */
326     public class MyMouseClickHandler1 implements XMouseClickHandler {
327         /**
328          * This event sets the member <code>m_mousePressed</coed> to
329          *  <code>true</code>
330          * @param oEvent The mouse event informs about the kind of mouse event.
331          * @return returns <CODE>TRUE</CODE> in erery case
332          */
mousePressed( MouseEvent oEvent )333         public boolean mousePressed( MouseEvent oEvent ){
334             log.println("XMouseClickHandler 1: mousePressed-Event");
335             m_mousePressed1 = true;
336             return true;
337         }
338         /**
339          * This event sets the member <code>m_mouseReleased</coed> to
340          *  <code>true</code>
341          * @param oEvent The mouse event informs about the kind of mouse event.
342          * @return returns <CODE>TRUE</CODE> in erery case
343          */
mouseReleased( MouseEvent oEvent )344         public boolean mouseReleased( MouseEvent oEvent ){
345             log.println("XMouseClickHandler 1: mouseReleased-Event");
346             m_mouseReleased1 = true;
347             return true;
348         }
349         /**
350          * This event does nothing usefull
351          * @param oEvent refers to the object that fired the event.
352          */
disposing( EventObject oEvent )353         public void disposing( EventObject oEvent ){
354             log.println("XMouseClickHandler 1: disposing-Event");
355         }
356     };
357 
358     /**
359      * Listener which added and removed. Its method must NOT be called
360      * on <code>mousePressed</code> and <code>mouseReleased</code> call.
361      */
362     public class MyMouseClickHandler2 implements XMouseClickHandler {
363         /**
364          * This event sets the member <code>m_mousePressed</coed> to
365          *  <code>true</code>
366          * @param oEvent The mouse event informs about the kind of mouse event.
367          * @return returns <CODE>TRUE</CODE> in erery case
368          */
mousePressed( MouseEvent oEvent )369         public boolean mousePressed( MouseEvent oEvent ){
370             log.println("XMouseClickHandler 2: mousePressed-Event: " +
371                         "This should not be happen because listener is removed!");
372             m_mousePressed2 = true;
373             return true;
374         }
375         /**
376          * This event sets the member <code>m_mouseReleased</coed> to
377          *  <code>true</code>
378          * @param oEvent The mouse event informs about the kind of mouse event.
379          * @return returns <CODE>TRUE</CODE> in erery case
380          */
mouseReleased( MouseEvent oEvent )381         public boolean mouseReleased( MouseEvent oEvent ){
382             log.println("XMouseClickHandler 2: mouseReleased-Event: " +
383                         "This should not be happen because listener is removed!");
384             m_mouseReleased2 = true;
385             return true;
386         }
387         /**
388          * This event does nothing usefull
389          * @param oEvent refers to the object that fired the event.
390          */
disposing( EventObject oEvent )391         public void disposing( EventObject oEvent ){
392             log.println("XMouseClickHandler 2: disposing-Event: " +
393                     "   This should not be happen because listener is removed!");
394         }
395     };
396 
397     /**
398      * To check the events this class is a thread which click a mouse button and
399      * press a key with the <CODE>Robot</CODE> class
400      * @see java.awt.Robot
401      */
402     private class EventTrigger extends Thread{
403 
404         /**
405          * represents a <CODE>AccessibilityTools</CODE>
406          */
407         private final AccessibilityTools at = new AccessibilityTools();
408         /**
409          * represents an <CODE>EventType</CODE>
410          * @see EventTest.EventTriggerType
411          */
412         private int eventType = 0;
413         /**
414          * represents a <CODE>XModel</CODE> of a document
415          */
416         private XModel xModel = null;
417 
418         /**
419          * Creates an instacne of this class. The parameter <CODE>eType</CODE> represents
420          * the kind of event wich will be triggert at <CODE>run()</CODE>
421          * @param model the model of a document
422          * @param eType the kind of event which should be trigger
423          */
EventTrigger(XModel model, int eType)424         public EventTrigger(XModel model, int eType)
425         {
426             this.xModel = model;
427             this.eventType = eType;
428         }
429 
430         /**
431          * Triggers the event wich is represented by <CODE>eventType</CODE>
432          * The scenarios are:
433          * <ul>
434          *    <li>EventTest.EventTriggerType.MOUSE_KLICK_INTO_DOC
435          *        which calls
436          *        <li><CODE>clickIntoDoc</CODE></LI>
437          *        </LI>
438          *    <li>EventTest.EventTriggerType.KEY_TEXT_INTO_DOC
439          *        which calls
440          *            <li><CODE>clickIntodoc</CODE></LI>
441          *            <li><CODE>keyIntoDoc</CODE></LI>
442          *    </LI>
443          * </UL>
444          */
run()445         public void run(){
446 
447             switch (this.eventType){
448 
449                 case EventTriggerType.MOUSE_KLICK_INTO_DOC:
450                     clickIntoDoc();
451                     break;
452                 case EventTriggerType.KEY_TEXT_INTO_DOC:
453                     clickIntoDoc();
454                     keyIntoDoc();
455                     break;
456 
457             }
458         }
459         /**
460          * This method cklicks into the middel of a document. It uses Accessibility
461          * to get the document and query for its position and its range to calculate
462          * the middle. This values was used for <CODE>Robot</CODE> Class. This
463          * Robot class is able to move the mouse and to cklick a mouse button
464          * @see java.awt.Robot
465         */
clickIntoDoc()466         private void clickIntoDoc(){
467             try{
468 
469                 util.DesktopTools.bringWindowToFront(xModel);
470 
471                 XWindow xWindow = at.getCurrentWindow(
472                                           (XMultiServiceFactory) tParam.getMSF(),
473                                           xModel);
474 
475                 XAccessible xRoot = at.getAccessibleObject(xWindow);
476 
477 
478 
479                 XAccessibleContext xPanel = at.getAccessibleObjectForRole(xRoot, AccessibleRole.PANEL);
480                 XAccessibleComponent xPanelCont = (XAccessibleComponent) UnoRuntime.queryInterface(XAccessibleComponent.class, xPanel);
481 
482                 // the position of the panel
483                 Point point = xPanelCont.getLocationOnScreen();
484 
485                 // the range of the panel
486                 Rectangle rect = xPanelCont.getBounds();
487 
488                 try {
489                     Robot rob = new Robot();
490                     int x = point.X + (rect.Width / 2);
491                     int y = point.Y + (rect.Height / 2);
492                     log.println("try to klick into the middle of the document");
493                     rob.mouseMove(x, y);
494                     rob.mousePress(InputEvent.BUTTON1_MASK);
495                     rob.mouseRelease(InputEvent.BUTTON1_MASK);
496                 } catch (java.awt.AWTException e) {
497                     log.println("couldn't press mouse button");
498                 }
499             } catch (java.lang.Exception e){
500                 log.println("could not click into the scroll bar: " + e.toString());
501             }
502         }
503 
504         /**
505          * This method press the "A" key. Therefore it uses the <CODE>Robot</CODE>
506          * class.
507          * @see java.awt.Robot
508         */
keyIntoDoc()509         private void keyIntoDoc(){
510             try {
511                 Robot rob = new Robot();
512                 log.println("try to press 'A'");
513                 rob.keyPress(java.awt.event.KeyEvent.VK_A);
514                 rob.keyRelease(java.awt.event.KeyEvent.VK_A);
515             } catch (java.awt.AWTException e) {
516                 log.println("couldn't press key");
517             }
518 
519         }
520     }
521 
522     /** This interface represents all possible actions which could be used
523      * in the <CODE>EventTrigger</CODE> class.
524      * @see EventTest.EventTrigger
525     */
526     private interface EventTriggerType{
527 
528         /** klick the mouse into the scroll bar*/
529         final public static int MOUSE_KLICK_INTO_DOC = 1;
530 
531         /** write some text into a spread sheet*/
532         final public static int KEY_TEXT_INTO_DOC = 2;
533     }
534 }
535 
536