188cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi/*
288cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi * Copyright (C) 2015 The Android Open Source Project
388cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi *
488cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi * Licensed under the Apache License, Version 2.0 (the "License");
588cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi * you may not use this file except in compliance with the License.
688cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi * You may obtain a copy of the License at
788cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi *
888cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi *      http://www.apache.org/licenses/LICENSE-2.0
988cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi *
1088cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi * Unless required by applicable law or agreed to in writing, software
1188cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi * distributed under the License is distributed on an "AS IS" BASIS,
1288cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1388cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi * See the License for the specific language governing permissions and
1488cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi * limitations under the License
1588cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi */
1688cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi
1788cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagipackage android.widget.espresso;
1888cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi
19a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagiimport static com.android.internal.util.Preconditions.checkNotNull;
20a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi
21a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagiimport java.lang.annotation.Retention;
22a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagiimport java.lang.annotation.RetentionPolicy;
23a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi
24a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagiimport android.annotation.IntDef;
2588cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagiimport android.support.test.espresso.InjectEventSecurityException;
2688cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagiimport android.support.test.espresso.UiController;
2788cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagiimport android.view.InputDevice;
2888cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagiimport android.view.KeyEvent;
2988cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagiimport android.view.MotionEvent;
3088cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi
3188cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi/**
3288cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi * Class to wrap an UiController to overwrite source of motion events to SOURCE_MOUSE.
3388cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi * Note that this doesn't change the tool type.
3488cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi */
35a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagipublic final class MouseUiController implements UiController {
36a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi    @Retention(RetentionPolicy.SOURCE)
37a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi    @IntDef({MotionEvent.BUTTON_PRIMARY, MotionEvent.BUTTON_SECONDARY, MotionEvent.BUTTON_TERTIARY})
38a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi    public @interface MouseButton {}
39a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi
4088cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    private final UiController mUiController;
41a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi    @MouseButton
42a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi    private final int mButton;
4388cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi
4488cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    public MouseUiController(UiController uiController) {
45a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi        this(uiController, MotionEvent.BUTTON_PRIMARY);
46a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi    }
47a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi
48a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi    /**
49a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi     * Constructs MouseUiController.
50a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi     *
51a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi     * @param uiController the uiController to wrap
52a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi     * @param button the button to be used for generating input events.
53a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi     */
54a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi    public MouseUiController(UiController uiController, @MouseButton int button) {
55a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi        mUiController = checkNotNull(uiController);
56a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi        mButton = button;
5788cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    }
5888cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi
5988cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    @Override
6088cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    public boolean injectKeyEvent(KeyEvent event) throws InjectEventSecurityException {
6188cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi        return mUiController.injectKeyEvent(event);
6288cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    }
6388cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi
6488cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    @Override
6588cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    public boolean injectMotionEvent(MotionEvent event) throws InjectEventSecurityException {
66a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi        // Modify the event to mimic mouse event.
6788cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi        event.setSource(InputDevice.SOURCE_MOUSE);
68a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi        if (event.getActionMasked() != MotionEvent.ACTION_UP) {
69a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi            event.setButtonState(mButton);
70a0b3c068810b2bc4ed61d9ad35e9660aa247d2f6Keisuke Kuroyanagi        }
7188cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi        return mUiController.injectMotionEvent(event);
7288cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    }
7388cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi
7488cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    @Override
7588cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    public boolean injectString(String str) throws InjectEventSecurityException {
7688cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi        return mUiController.injectString(str);
7788cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    }
7888cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi
7988cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    @Override
8088cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    public void loopMainThreadForAtLeast(long millisDelay) {
8188cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi        mUiController.loopMainThreadForAtLeast(millisDelay);
8288cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    }
8388cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi
8488cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    @Override
8588cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    public void loopMainThreadUntilIdle() {
8688cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi        mUiController.loopMainThreadUntilIdle();
8788cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi    }
8888cabede9bc74ade7d0124cde3d40fadb6c97a85Keisuke Kuroyanagi}
89