Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2018 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 
     17 #include <gtest/gtest.h>
     18 #include <stdlib.h>
     19 #include <unistd.h>
     20 #include <sys/time.h>
     21 #include <sys/types.h>
     22 #include <stdio.h>
     23 #include <poll.h>
     24 
     25 #include <memory>
     26 
     27 #include <android/native_window.h>
     28 
     29 #include <binder/Binder.h>
     30 #include <binder/IServiceManager.h>
     31 #include <binder/Parcel.h>
     32 #include <binder/ProcessState.h>
     33 
     34 #include <gui/ISurfaceComposer.h>
     35 #include <gui/Surface.h>
     36 #include <gui/SurfaceComposerClient.h>
     37 #include <gui/SurfaceControl.h>
     38 
     39 #include <input/InputWindow.h>
     40 #include <input/IInputFlinger.h>
     41 #include <input/InputTransport.h>
     42 #include <input/Input.h>
     43 
     44 #include <ui/DisplayInfo.h>
     45 #include <ui/Rect.h>
     46 #include <ui/Region.h>
     47 
     48 
     49 namespace android {
     50 namespace test {
     51 
     52 using Transaction = SurfaceComposerClient::Transaction;
     53 
     54 sp<IInputFlinger> getInputFlinger() {
     55    sp<IBinder> input(defaultServiceManager()->getService(
     56             String16("inputflinger")));
     57     if (input == nullptr) {
     58         ALOGE("Failed to link to input service");
     59     } else { ALOGE("Linked to input"); }
     60     return interface_cast<IInputFlinger>(input);
     61 }
     62 
     63 // We use the top 10 layers as a way to haphazardly place ourselves above anything else.
     64 static const int LAYER_BASE = INT32_MAX - 10;
     65 
     66 class InputSurface {
     67 public:
     68     InputSurface(const sp<SurfaceControl> &sc, int width, int height) {
     69         mSurfaceControl = sc;
     70 
     71         InputChannel::openInputChannelPair("testchannels", mServerChannel, mClientChannel);
     72         mServerChannel->setToken(new BBinder());
     73 
     74         mInputFlinger = getInputFlinger();
     75         mInputFlinger->registerInputChannel(mServerChannel);
     76 
     77         populateInputInfo(width, height);
     78 
     79         mInputConsumer = new InputConsumer(mClientChannel);
     80     }
     81 
     82     static std::unique_ptr<InputSurface> makeColorInputSurface(const sp<SurfaceComposerClient> &scc,
     83                                                                int width, int height) {
     84         sp<SurfaceControl> surfaceControl =
     85                 scc->createSurface(String8("Test Surface"), 0 /* bufHeight */, 0 /* bufWidth */,
     86                                    PIXEL_FORMAT_RGBA_8888, ISurfaceComposerClient::eFXSurfaceColor);
     87         return std::make_unique<InputSurface>(surfaceControl, width, height);
     88     }
     89 
     90     static std::unique_ptr<InputSurface> makeBufferInputSurface(
     91             const sp<SurfaceComposerClient> &scc, int width, int height) {
     92         sp<SurfaceControl> surfaceControl =
     93                 scc->createSurface(String8("Test Buffer Surface"), width, height,
     94                                    PIXEL_FORMAT_RGBA_8888, 0 /* flags */);
     95         return std::make_unique<InputSurface>(surfaceControl, width, height);
     96     }
     97 
     98     static std::unique_ptr<InputSurface> makeContainerInputSurface(
     99             const sp<SurfaceComposerClient> &scc, int width, int height) {
    100         sp<SurfaceControl> surfaceControl =
    101                 scc->createSurface(String8("Test Container Surface"), 0 /* bufHeight */,
    102                                    0 /* bufWidth */, PIXEL_FORMAT_RGBA_8888,
    103                                    ISurfaceComposerClient::eFXSurfaceContainer);
    104         return std::make_unique<InputSurface>(surfaceControl, width, height);
    105     }
    106 
    107     InputEvent* consumeEvent() {
    108         waitForEventAvailable();
    109 
    110         InputEvent *ev;
    111         uint32_t seqId;
    112         status_t consumed = mInputConsumer->consume(&mInputEventFactory, true, -1, &seqId, &ev);
    113         if (consumed != OK) {
    114             return nullptr;
    115         }
    116         mInputConsumer->sendFinishedSignal(seqId, true);
    117         return ev;
    118     }
    119 
    120     void expectTap(int x, int y) {
    121         InputEvent* ev = consumeEvent();
    122         EXPECT_TRUE(ev != nullptr);
    123         EXPECT_TRUE(ev->getType() == AINPUT_EVENT_TYPE_MOTION);
    124         MotionEvent* mev = static_cast<MotionEvent*>(ev);
    125         EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
    126         EXPECT_EQ(x, mev->getX(0));
    127         EXPECT_EQ(y, mev->getY(0));
    128 
    129         ev = consumeEvent();
    130         EXPECT_TRUE(ev != nullptr);
    131         EXPECT_TRUE(ev->getType() == AINPUT_EVENT_TYPE_MOTION);
    132         mev = static_cast<MotionEvent*>(ev);
    133         EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
    134     }
    135 
    136     void expectMotionEvent(int motionEventType, int x, int y) {
    137         InputEvent *ev = consumeEvent();
    138         ASSERT_NE(ev, nullptr);
    139         ASSERT_EQ(ev->getType(), AINPUT_EVENT_TYPE_MOTION);
    140         MotionEvent *mev = static_cast<MotionEvent *>(ev);
    141         EXPECT_EQ(motionEventType, mev->getAction());
    142         EXPECT_EQ(x, mev->getX(0));
    143         EXPECT_EQ(y, mev->getY(0));
    144     }
    145 
    146     void expectNoMotionEvent(int motionEventType) {
    147         InputEvent *ev = consumeEvent();
    148         if (ev == nullptr || ev->getType() != AINPUT_EVENT_TYPE_MOTION) {
    149             // Didn't find an event or a motion event so assume action didn't occur.
    150             return;
    151         }
    152 
    153         MotionEvent *mev = static_cast<MotionEvent *>(ev);
    154         EXPECT_NE(motionEventType, mev->getAction());
    155     }
    156 
    157     ~InputSurface() {
    158         mInputFlinger->unregisterInputChannel(mServerChannel);
    159     }
    160 
    161     void doTransaction(std::function<void(SurfaceComposerClient::Transaction&,
    162                     const sp<SurfaceControl>&)> transactionBody) {
    163         SurfaceComposerClient::Transaction t;
    164         transactionBody(t, mSurfaceControl);
    165         t.apply(true);
    166     }
    167 
    168     void showAt(int x, int y) {
    169         SurfaceComposerClient::Transaction t;
    170         t.show(mSurfaceControl);
    171         t.setInputWindowInfo(mSurfaceControl, mInputInfo);
    172         t.setLayer(mSurfaceControl, LAYER_BASE);
    173         t.setPosition(mSurfaceControl, x, y);
    174         t.setCrop_legacy(mSurfaceControl, Rect(0, 0, 100, 100));
    175         t.setAlpha(mSurfaceControl, 1);
    176         t.apply(true);
    177     }
    178 
    179 private:
    180     void waitForEventAvailable() {
    181         struct pollfd fd;
    182 
    183         fd.fd = mClientChannel->getFd();
    184         fd.events = POLLIN;
    185         poll(&fd, 1, 3000);
    186     }
    187 
    188     void populateInputInfo(int width, int height) {
    189         mInputInfo.token = mServerChannel->getToken();
    190         mInputInfo.name = "Test info";
    191         mInputInfo.layoutParamsFlags = InputWindowInfo::FLAG_NOT_TOUCH_MODAL;
    192         mInputInfo.layoutParamsType = InputWindowInfo::TYPE_BASE_APPLICATION;
    193         mInputInfo.dispatchingTimeout = 100000;
    194         mInputInfo.globalScaleFactor = 1.0;
    195         mInputInfo.canReceiveKeys = true;
    196         mInputInfo.hasFocus = true;
    197         mInputInfo.hasWallpaper = false;
    198         mInputInfo.paused = false;
    199 
    200         mInputInfo.touchableRegion.orSelf(Rect(0, 0, width, height));
    201 
    202         // TODO: Fill in from SF?
    203         mInputInfo.ownerPid = 11111;
    204         mInputInfo.ownerUid = 11111;
    205         mInputInfo.inputFeatures = 0;
    206         mInputInfo.displayId = 0;
    207 
    208         InputApplicationInfo aInfo;
    209         aInfo.token = new BBinder();
    210         aInfo.name = "Test app info";
    211         aInfo.dispatchingTimeout = 100000;
    212 
    213         mInputInfo.applicationInfo = aInfo;
    214     }
    215 public:
    216     sp<SurfaceControl> mSurfaceControl;
    217     sp<InputChannel> mServerChannel, mClientChannel;
    218     sp<IInputFlinger> mInputFlinger;
    219 
    220     InputWindowInfo mInputInfo;
    221 
    222     PreallocatedInputEventFactory mInputEventFactory;
    223     InputConsumer* mInputConsumer;
    224 };
    225 
    226 class InputSurfacesTest : public ::testing::Test {
    227 public:
    228     InputSurfacesTest() {
    229         ProcessState::self()->startThreadPool();
    230     }
    231 
    232     void SetUp() {
    233         mComposerClient = new SurfaceComposerClient;
    234         ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
    235 
    236         const auto display = mComposerClient->getInternalDisplayToken();
    237         ASSERT_FALSE(display == nullptr);
    238 
    239         DisplayInfo info;
    240         ASSERT_EQ(NO_ERROR, mComposerClient->getDisplayInfo(display, &info));
    241 
    242         // After a new buffer is queued, SurfaceFlinger is notified and will
    243         // latch the new buffer on next vsync.  Let's heuristically wait for 3
    244         // vsyncs.
    245         mBufferPostDelay = int32_t(1e6 / info.fps) * 3;
    246     }
    247 
    248     void TearDown() {
    249         mComposerClient->dispose();
    250     }
    251 
    252     std::unique_ptr<InputSurface> makeSurface(int width, int height) {
    253         return InputSurface::makeColorInputSurface(mComposerClient, width, height);
    254     }
    255 
    256     void postBuffer(const sp<SurfaceControl> &layer) {
    257         // wait for previous transactions (such as setSize) to complete
    258         Transaction().apply(true);
    259         ANativeWindow_Buffer buffer = {};
    260         EXPECT_EQ(NO_ERROR, layer->getSurface()->lock(&buffer, nullptr));
    261         ASSERT_EQ(NO_ERROR, layer->getSurface()->unlockAndPost());
    262         // Request an empty transaction to get applied synchronously to ensure the buffer is
    263         // latched.
    264         Transaction().apply(true);
    265         usleep(mBufferPostDelay);
    266     }
    267 
    268     sp<SurfaceComposerClient> mComposerClient;
    269     int32_t mBufferPostDelay;
    270 };
    271 
    272 void injectTap(int x, int y) {
    273     char *buf1, *buf2;
    274     asprintf(&buf1, "%d", x);
    275     asprintf(&buf2, "%d", y);
    276     if (fork() == 0) {
    277         execlp("input", "input", "tap", buf1, buf2, NULL);
    278     }
    279 }
    280 
    281 void injectMotionEvent(std::string event, int x, int y) {
    282     char *buf1, *buf2;
    283     asprintf(&buf1, "%d", x);
    284     asprintf(&buf2, "%d", y);
    285     if (fork() == 0) {
    286         execlp("input", "input", "motionevent", event.c_str(), buf1, buf2, NULL);
    287     }
    288 }
    289 
    290 TEST_F(InputSurfacesTest, can_receive_input) {
    291     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    292     surface->showAt(100, 100);
    293 
    294     injectTap(101, 101);
    295 
    296     EXPECT_TRUE(surface->consumeEvent() != nullptr);
    297 }
    298 
    299 TEST_F(InputSurfacesTest, input_respects_positioning) {
    300     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    301     surface->showAt(100, 100);
    302 
    303     std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100);
    304     surface2->showAt(200, 200);
    305 
    306     injectTap(201, 201);
    307     surface2->expectTap(1, 1);
    308 
    309     injectTap(101, 101);
    310     surface->expectTap(1, 1);
    311 
    312     surface2->doTransaction([](auto &t, auto &sc) {
    313          t.setPosition(sc, 100, 100);
    314     });
    315     surface->doTransaction([](auto &t, auto &sc) {
    316          t.setPosition(sc, 200, 200);
    317     });
    318 
    319     injectTap(101, 101);
    320     surface2->expectTap(1, 1);
    321 
    322     injectTap(201, 201);
    323     surface->expectTap(1, 1);
    324 }
    325 
    326 TEST_F(InputSurfacesTest, input_respects_layering) {
    327     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    328     std::unique_ptr<InputSurface> surface2 = makeSurface(100, 100);
    329 
    330     surface->showAt(10, 10);
    331     surface2->showAt(10, 10);
    332 
    333     surface->doTransaction([](auto &t, auto &sc) {
    334          t.setLayer(sc, LAYER_BASE + 1);
    335     });
    336 
    337     injectTap(11, 11);
    338     surface->expectTap(1, 1);
    339 
    340     surface2->doTransaction([](auto &t, auto &sc) {
    341          t.setLayer(sc, LAYER_BASE + 1);
    342     });
    343 
    344     injectTap(11, 11);
    345     surface2->expectTap(1, 1);
    346 
    347     surface2->doTransaction([](auto &t, auto &sc) {
    348          t.hide(sc);
    349     });
    350 
    351     injectTap(11, 11);
    352     surface->expectTap(1, 1);
    353 }
    354 
    355 // Surface Insets are set to offset the client content and draw a border around the client surface
    356 // (such as shadows in dialogs). Inputs sent to the client are offset such that 0,0 is the start
    357 // of the client content.
    358 TEST_F(InputSurfacesTest, input_respects_surface_insets) {
    359     std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    360     std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
    361     bgSurface->showAt(100, 100);
    362 
    363     fgSurface->mInputInfo.surfaceInset = 5;
    364     fgSurface->showAt(100, 100);
    365 
    366     injectTap(106, 106);
    367     fgSurface->expectTap(1, 1);
    368 
    369     injectTap(101, 101);
    370     bgSurface->expectTap(1, 1);
    371 }
    372 
    373 // Ensure a surface whose insets are cropped, handles the touch offset correctly. ref:b/120413463
    374 TEST_F(InputSurfacesTest, input_respects_cropped_surface_insets) {
    375     std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
    376     std::unique_ptr<InputSurface> childSurface = makeSurface(100, 100);
    377     parentSurface->showAt(100, 100);
    378 
    379     childSurface->mInputInfo.surfaceInset = 10;
    380     childSurface->showAt(100, 100);
    381 
    382     childSurface->doTransaction([&](auto &t, auto &sc) {
    383         t.setPosition(sc, -5, -5);
    384         t.reparent(sc, parentSurface->mSurfaceControl->getHandle());
    385     });
    386 
    387     injectTap(106, 106);
    388     childSurface->expectTap(1, 1);
    389 
    390     injectTap(101, 101);
    391     parentSurface->expectTap(1, 1);
    392 }
    393 
    394 // Ensure a surface whose insets are scaled, handles the touch offset correctly.
    395 TEST_F(InputSurfacesTest, input_respects_scaled_surface_insets) {
    396     std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    397     std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
    398     bgSurface->showAt(100, 100);
    399 
    400     fgSurface->mInputInfo.surfaceInset = 5;
    401     fgSurface->showAt(100, 100);
    402 
    403     fgSurface->doTransaction([&](auto &t, auto &sc) { t.setMatrix(sc, 2.0, 0, 0, 4.0); });
    404 
    405     // expect = touch / scale - inset
    406     injectTap(112, 124);
    407     fgSurface->expectTap(1, 1);
    408 
    409     injectTap(101, 101);
    410     bgSurface->expectTap(1, 1);
    411 }
    412 
    413 // Ensure we ignore transparent region when getting screen bounds when positioning input frame.
    414 TEST_F(InputSurfacesTest, input_ignores_transparent_region) {
    415     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    416     surface->doTransaction([](auto &t, auto &sc) {
    417         Region transparentRegion(Rect(0, 0, 10, 10));
    418         t.setTransparentRegionHint(sc, transparentRegion);
    419     });
    420     surface->showAt(100, 100);
    421     injectTap(101, 101);
    422     surface->expectTap(1, 1);
    423 }
    424 
    425 // Ensure we send the input to the right surface when the surface visibility changes due to the
    426 // first buffer being submitted. ref: b/120839715
    427 TEST_F(InputSurfacesTest, input_respects_buffer_layer_buffer) {
    428     std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    429     std::unique_ptr<InputSurface> bufferSurface =
    430             InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);
    431 
    432     bgSurface->showAt(10, 10);
    433     bufferSurface->showAt(10, 10);
    434 
    435     injectTap(11, 11);
    436     bgSurface->expectTap(1, 1);
    437 
    438     postBuffer(bufferSurface->mSurfaceControl);
    439     injectTap(11, 11);
    440     bufferSurface->expectTap(1, 1);
    441 }
    442 
    443 TEST_F(InputSurfacesTest, input_respects_buffer_layer_alpha) {
    444     std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    445     std::unique_ptr<InputSurface> bufferSurface =
    446             InputSurface::makeBufferInputSurface(mComposerClient, 100, 100);
    447     postBuffer(bufferSurface->mSurfaceControl);
    448 
    449     bgSurface->showAt(10, 10);
    450     bufferSurface->showAt(10, 10);
    451 
    452     injectTap(11, 11);
    453     bufferSurface->expectTap(1, 1);
    454 
    455     bufferSurface->doTransaction([](auto &t, auto &sc) { t.setAlpha(sc, 0.0); });
    456 
    457     injectTap(11, 11);
    458     bgSurface->expectTap(1, 1);
    459 }
    460 
    461 TEST_F(InputSurfacesTest, input_respects_color_layer_alpha) {
    462     std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    463     std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
    464 
    465     bgSurface->showAt(10, 10);
    466     fgSurface->showAt(10, 10);
    467 
    468     injectTap(11, 11);
    469     fgSurface->expectTap(1, 1);
    470 
    471     fgSurface->doTransaction([](auto &t, auto &sc) { t.setAlpha(sc, 0.0); });
    472 
    473     injectTap(11, 11);
    474     bgSurface->expectTap(1, 1);
    475 }
    476 
    477 TEST_F(InputSurfacesTest, input_respects_container_layer_visiblity) {
    478     std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
    479     std::unique_ptr<InputSurface> containerSurface =
    480             InputSurface::makeContainerInputSurface(mComposerClient, 100, 100);
    481 
    482     bgSurface->showAt(10, 10);
    483     containerSurface->showAt(10, 10);
    484 
    485     injectTap(11, 11);
    486     containerSurface->expectTap(1, 1);
    487 
    488     containerSurface->doTransaction([](auto &t, auto &sc) { t.hide(sc); });
    489 
    490     injectTap(11, 11);
    491     bgSurface->expectTap(1, 1);
    492 }
    493 
    494 TEST_F(InputSurfacesTest, transfer_touch_focus) {
    495     std::unique_ptr<InputSurface> fromSurface = makeSurface(100, 100);
    496 
    497     fromSurface->showAt(10, 10);
    498     injectMotionEvent("DOWN", 11, 11);
    499     fromSurface->expectMotionEvent(AMOTION_EVENT_ACTION_DOWN, 1, 1);
    500 
    501     std::unique_ptr<InputSurface> toSurface = makeSurface(100, 100);
    502     toSurface->showAt(10, 10);
    503 
    504     sp<IBinder> fromToken = fromSurface->mServerChannel->getToken();
    505     sp<IBinder> toToken = toSurface->mServerChannel->getToken();
    506     SurfaceComposerClient::Transaction t;
    507     t.transferTouchFocus(fromToken, toToken).apply(true);
    508 
    509     injectMotionEvent("UP", 11, 11);
    510     toSurface->expectMotionEvent(AMOTION_EVENT_ACTION_UP, 1, 1);
    511     fromSurface->expectNoMotionEvent(AMOTION_EVENT_ACTION_UP);
    512 }
    513 
    514 TEST_F(InputSurfacesTest, input_respects_outscreen) {
    515     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
    516     surface->showAt(-1, -1);
    517 
    518     injectTap(0, 0);
    519     surface->expectTap(1, 1);
    520 }
    521 }
    522 }
    523