1/*
2 * Copyright (C) 2015 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 android.widget.espresso;
18
19import static com.android.internal.util.Preconditions.checkNotNull;
20
21import java.lang.annotation.Retention;
22import java.lang.annotation.RetentionPolicy;
23
24import android.annotation.IntDef;
25import android.support.test.espresso.InjectEventSecurityException;
26import android.support.test.espresso.UiController;
27import android.view.InputDevice;
28import android.view.KeyEvent;
29import android.view.MotionEvent;
30
31/**
32 * Class to wrap an UiController to overwrite source of motion events to SOURCE_MOUSE.
33 * Note that this doesn't change the tool type.
34 */
35public final class MouseUiController implements UiController {
36    @Retention(RetentionPolicy.SOURCE)
37    @IntDef({MotionEvent.BUTTON_PRIMARY, MotionEvent.BUTTON_SECONDARY, MotionEvent.BUTTON_TERTIARY})
38    public @interface MouseButton {}
39
40    private final UiController mUiController;
41    @MouseButton
42    private final int mButton;
43
44    public MouseUiController(UiController uiController) {
45        this(uiController, MotionEvent.BUTTON_PRIMARY);
46    }
47
48    /**
49     * Constructs MouseUiController.
50     *
51     * @param uiController the uiController to wrap
52     * @param button the button to be used for generating input events.
53     */
54    public MouseUiController(UiController uiController, @MouseButton int button) {
55        mUiController = checkNotNull(uiController);
56        mButton = button;
57    }
58
59    @Override
60    public boolean injectKeyEvent(KeyEvent event) throws InjectEventSecurityException {
61        return mUiController.injectKeyEvent(event);
62    }
63
64    @Override
65    public boolean injectMotionEvent(MotionEvent event) throws InjectEventSecurityException {
66        // Modify the event to mimic mouse event.
67        event.setSource(InputDevice.SOURCE_MOUSE);
68        if (event.getActionMasked() != MotionEvent.ACTION_UP) {
69            event.setButtonState(mButton);
70        }
71        return mUiController.injectMotionEvent(event);
72    }
73
74    @Override
75    public boolean injectString(String str) throws InjectEventSecurityException {
76        return mUiController.injectString(str);
77    }
78
79    @Override
80    public void loopMainThreadForAtLeast(long millisDelay) {
81        mUiController.loopMainThreadForAtLeast(millisDelay);
82    }
83
84    @Override
85    public void loopMainThreadUntilIdle() {
86        mUiController.loopMainThreadUntilIdle();
87    }
88}
89