Interface for multiple virtual touchpads.

This passes the touchpad selection across binder, but does not yet
actually implement multiple touchpad devices.

Bug: b/35992608
Test: primary only in VirtualTouchpad_test
Change-Id: I7529735362e0e38805b9c0e52e07b5efc86bd535
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp b/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp
index 23a2e31..175173f 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp
+++ b/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp
@@ -12,19 +12,20 @@
  public:
   VirtualTouchpadClientImpl(sp<IVirtualTouchpadService> service)
       : service_(service) {}
-  ~VirtualTouchpadClientImpl() {}
+  ~VirtualTouchpadClientImpl() override {}
 
-  status_t Touch(float x, float y, float pressure) override {
+  status_t Touch(int touchpad,
+                 float x, float y, float pressure) override {
     if (service_ == nullptr) {
       return NO_INIT;
     }
-    return service_->touch(x, y, pressure).transactionError();
+    return service_->touch(touchpad, x, y, pressure).transactionError();
   }
-  status_t ButtonState(int buttons) override {
+  status_t ButtonState(int touchpad, int buttons) override {
     if (service_ == nullptr) {
       return NO_INIT;
     }
-    return service_->buttonState(buttons).transactionError();
+    return service_->buttonState(touchpad, buttons).transactionError();
   }
 
  private:
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
index ae31156..f25a2ad 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
+++ b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.cpp
@@ -56,15 +56,17 @@
   return injector_->GetError();
 }
 
-int VirtualTouchpadEvdev::Touch(float x, float y, float pressure) {
+int VirtualTouchpadEvdev::Touch(int touchpad, float x, float y,
+                                float pressure) {
+  (void)touchpad; // TODO(b/35992608) Support multiple virtual touchpad devices.
   if ((x < 0.0f) || (x >= 1.0f) || (y < 0.0f) || (y >= 1.0f)) {
     return EINVAL;
   }
   int32_t device_x = x * kWidth;
   int32_t device_y = y * kHeight;
   touches_ = ((touches_ & 1) << 1) | (pressure > 0);
-  ALOGV("(%f,%f) %f -> (%" PRId32 ",%" PRId32 ") %d",
-        x, y, pressure, device_x, device_y, touches_);
+  ALOGV("(%f,%f) %f -> (%" PRId32 ",%" PRId32 ") %d", x, y, pressure, device_x,
+        device_y, touches_);
 
   if (!injector_) {
     return EvdevInjector::ERROR_SEQUENCING;
@@ -101,7 +103,8 @@
   return injector_->GetError();
 }
 
-int VirtualTouchpadEvdev::ButtonState(int buttons) {
+int VirtualTouchpadEvdev::ButtonState(int touchpad, int buttons) {
+  (void)touchpad; // TODO(b/35992608) Support multiple virtual touchpad devices.
   const int changes = last_motion_event_buttons_ ^ buttons;
   if (!changes) {
     return 0;
@@ -117,10 +120,9 @@
   }
   injector_->ResetError();
   if (changes & AMOTION_EVENT_BUTTON_BACK) {
-    injector_->SendKey(BTN_BACK,
-                       (buttons & AMOTION_EVENT_BUTTON_BACK)
-                           ? EvdevInjector::KEY_PRESS
-                           : EvdevInjector::KEY_RELEASE);
+    injector_->SendKey(BTN_BACK, (buttons & AMOTION_EVENT_BUTTON_BACK)
+                                     ? EvdevInjector::KEY_PRESS
+                                     : EvdevInjector::KEY_RELEASE);
   }
   last_motion_event_buttons_ = buttons;
   return injector_->GetError();
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.h b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.h
index c763529..ec8006b 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpadEvdev.h
+++ b/services/vr/virtual_touchpad/VirtualTouchpadEvdev.h
@@ -18,12 +18,12 @@
   static sp<VirtualTouchpad> Create();
 
   // VirtualTouchpad implementation:
-  status_t Touch(float x, float y, float pressure) override;
-  status_t ButtonState(int buttons) override;
+  status_t Touch(int touchpad, float x, float y, float pressure) override;
+  status_t ButtonState(int touchpad, int buttons) override;
 
  protected:
   VirtualTouchpadEvdev() {}
-  ~VirtualTouchpadEvdev() {}
+  ~VirtualTouchpadEvdev() override {}
   status_t Initialize();
 
   // Must be called only between construction and Initialize().
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadService.cpp b/services/vr/virtual_touchpad/VirtualTouchpadService.cpp
index 3fcb8fc..a1f281c 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpadService.cpp
+++ b/services/vr/virtual_touchpad/VirtualTouchpadService.cpp
@@ -8,16 +8,15 @@
 namespace android {
 namespace dvr {
 
-binder::Status VirtualTouchpadService::touch(float x, float y, float pressure) {
-  const status_t error = touchpad_->Touch(x, y, pressure);
-  return error ? binder::Status::fromStatusT(error)
-               : binder::Status::ok();
+binder::Status VirtualTouchpadService::touch(int touchpad,
+                                             float x, float y, float pressure) {
+  const status_t error = touchpad_->Touch(touchpad, x, y, pressure);
+  return error ? binder::Status::fromStatusT(error) : binder::Status::ok();
 }
 
-binder::Status VirtualTouchpadService::buttonState(int buttons) {
-  const status_t error = touchpad_->ButtonState(buttons);
-  return error ? binder::Status::fromStatusT(error)
-               : binder::Status::ok();
+binder::Status VirtualTouchpadService::buttonState(int touchpad, int buttons) {
+  const status_t error = touchpad_->ButtonState(touchpad, buttons);
+  return error ? binder::Status::fromStatusT(error) : binder::Status::ok();
 }
 
 }  // namespace dvr
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadService.h b/services/vr/virtual_touchpad/VirtualTouchpadService.h
index b832c8f..9b880b2 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpadService.h
+++ b/services/vr/virtual_touchpad/VirtualTouchpadService.h
@@ -15,11 +15,12 @@
  public:
   VirtualTouchpadService(sp<VirtualTouchpad> touchpad)
       : touchpad_(touchpad) {}
+  ~VirtualTouchpadService() override {}
 
  protected:
   // Implements IVirtualTouchpadService.
-  binder::Status touch(float x, float y, float pressure) override;
-  binder::Status buttonState(int buttons) override;
+  binder::Status touch(int touchpad, float x, float y, float pressure) override;
+  binder::Status buttonState(int touchpad, int buttons) override;
 
  private:
   sp<VirtualTouchpad> touchpad_;
diff --git a/services/vr/virtual_touchpad/aidl/android/dvr/VirtualTouchpadService.aidl b/services/vr/virtual_touchpad/aidl/android/dvr/VirtualTouchpadService.aidl
index c2044da..496c5e2 100644
--- a/services/vr/virtual_touchpad/aidl/android/dvr/VirtualTouchpadService.aidl
+++ b/services/vr/virtual_touchpad/aidl/android/dvr/VirtualTouchpadService.aidl
@@ -8,18 +8,20 @@
   /**
    * Generate a simulated touch event.
    *
+   * @param touchpad Selects touchpad.
    * @param x Horizontal touch position.
    * @param y Vertical touch position.
    * @param pressure Touch pressure; use 0.0 for no touch (lift or hover).
    *
    * Position values in the range [0.0, 1.0) map to the screen.
    */
-  void touch(float x, float y, float pressure);
+  void touch(int touchpad, float x, float y, float pressure);
 
   /**
    * Generate a simulated touchpad button state event.
    *
+   * @param touchpad Selects touchpad.
    * @param buttons A union of MotionEvent BUTTON_* values.
    */
-  void buttonState(int buttons);
+  void buttonState(int touchpad, int buttons);
 }
diff --git a/services/vr/virtual_touchpad/include/VirtualTouchpad.h b/services/vr/virtual_touchpad/include/VirtualTouchpad.h
index bbaf69b..d24d121 100644
--- a/services/vr/virtual_touchpad/include/VirtualTouchpad.h
+++ b/services/vr/virtual_touchpad/include/VirtualTouchpad.h
@@ -12,6 +12,11 @@
 //
 class VirtualTouchpad : public RefBase {
  public:
+  enum : int {
+    PRIMARY = 0,
+    VIRTUAL = 1,
+  };
+
   // Create a virtual touchpad.
   // Implementations should provide this, and hide their constructors.
   // For the user, switching implementations should be as simple as changing
@@ -22,6 +27,7 @@
 
   // Generate a simulated touch event.
   //
+  // @param touchpad Touchpad selector index.
   // @param x Horizontal touch position.
   // @param y Vertical touch position.
   //            Values must be in the range [0.0, 1.0).
@@ -30,21 +36,22 @@
   //            is binary. Use 0.0f for no contact.
   // @returns OK on success.
   //
-  virtual status_t Touch(float x, float y, float pressure) = 0;
+  virtual status_t Touch(int touchpad, float x, float y, float pressure) = 0;
 
   // Generate a simulated touchpad button state.
   //
+  // @param touchpad Touchpad selector index.
   // @param buttons A union of MotionEvent BUTTON_* values.
   // @returns OK on success.
   //
   // Currently only BUTTON_BACK is supported, as the implementation
   // restricts itself to operations actually required by VrWindowManager.
   //
-  virtual status_t ButtonState(int buttons) = 0;
+  virtual status_t ButtonState(int touchpad, int buttons) = 0;
 
  protected:
   VirtualTouchpad() {}
-  virtual ~VirtualTouchpad() {}
+  ~VirtualTouchpad() override {}
 
  private:
   VirtualTouchpad(const VirtualTouchpad&) = delete;
diff --git a/services/vr/virtual_touchpad/include/VirtualTouchpadClient.h b/services/vr/virtual_touchpad/include/VirtualTouchpadClient.h
index 46bec0e..dd9c265 100644
--- a/services/vr/virtual_touchpad/include/VirtualTouchpadClient.h
+++ b/services/vr/virtual_touchpad/include/VirtualTouchpadClient.h
@@ -13,12 +13,12 @@
  public:
   // VirtualTouchpad implementation:
   static sp<VirtualTouchpad> Create();
-  status_t Touch(float x, float y, float pressure) override;
-  status_t ButtonState(int buttons) override;
+  status_t Touch(int touchpad, float x, float y, float pressure) override;
+  status_t ButtonState(int touchpad, int buttons) override;
 
  protected:
   VirtualTouchpadClient() {}
-  virtual ~VirtualTouchpadClient() {}
+  ~VirtualTouchpadClient() override {}
 
  private:
   VirtualTouchpadClient(const VirtualTouchpadClient&) = delete;
diff --git a/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp b/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
index b448fd1..469a2d0 100644
--- a/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
+++ b/services/vr/virtual_touchpad/tests/VirtualTouchpad_test.cpp
@@ -15,6 +15,7 @@
 
 class UInputForTesting : public EvdevInjector::UInput {
  public:
+  ~UInputForTesting() override {}
   void WriteInputEvent(uint16_t type, uint16_t code, int32_t value) {
     struct input_event event;
     memset(&event, 0, sizeof(event));
@@ -30,7 +31,7 @@
 class UInputRecorder : public UInputForTesting {
  public:
   UInputRecorder() {}
-  virtual ~UInputRecorder() {}
+  ~UInputRecorder() override {}
 
   const std::string& GetString() const { return s_; }
   void Reset() { s_.clear(); }
@@ -157,7 +158,7 @@
 
   expect.Reset();
   record.Reset();
-  int touch_status = touchpad->Touch(0, 0, 0);
+  int touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 0, 0, 0);
   EXPECT_EQ(0, touch_status);
   expect.WriteInputEvent(EV_ABS, ABS_MT_SLOT, 0);
   expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0);
@@ -168,7 +169,7 @@
 
   expect.Reset();
   record.Reset();
-  touch_status = touchpad->Touch(0.25f, 0.75f, 0.5f);
+  touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 0.25f, 0.75f, 0.5f);
   EXPECT_EQ(0, touch_status);
   expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0);
   expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, 0.25f * width);
@@ -179,7 +180,7 @@
 
   expect.Reset();
   record.Reset();
-  touch_status = touchpad->Touch(1.0f, 1.0f, 1.0f);
+  touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 1.0f, 1.0f, 1.0f);
   EXPECT_EQ(0, touch_status);
   expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, 0);
   expect.WriteInputEvent(EV_ABS, ABS_MT_POSITION_X, width);
@@ -189,7 +190,8 @@
 
   expect.Reset();
   record.Reset();
-  touch_status = touchpad->Touch(0.25f, 0.75f, -0.01f);
+  touch_status =
+      touchpad->Touch(VirtualTouchpad::PRIMARY, 0.25f, 0.75f, -0.01f);
   EXPECT_EQ(0, touch_status);
   expect.WriteInputEvent(EV_KEY, BTN_TOUCH, EvdevInjector::KEY_RELEASE);
   expect.WriteInputEvent(EV_ABS, ABS_MT_TRACKING_ID, -1);
@@ -198,7 +200,8 @@
 
   expect.Reset();
   record.Reset();
-  touch_status = touchpad->ButtonState(AMOTION_EVENT_BUTTON_BACK);
+  touch_status = touchpad->ButtonState(VirtualTouchpad::PRIMARY,
+                                       AMOTION_EVENT_BUTTON_BACK);
   EXPECT_EQ(0, touch_status);
   expect.WriteInputEvent(EV_KEY, BTN_BACK, EvdevInjector::KEY_PRESS);
   expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
@@ -206,13 +209,14 @@
 
   expect.Reset();
   record.Reset();
-  touch_status = touchpad->ButtonState(AMOTION_EVENT_BUTTON_BACK);
+  touch_status = touchpad->ButtonState(VirtualTouchpad::PRIMARY,
+                                       AMOTION_EVENT_BUTTON_BACK);
   EXPECT_EQ(0, touch_status);
   EXPECT_EQ(expect.GetString(), record.GetString());
 
   expect.Reset();
   record.Reset();
-  touch_status = touchpad->ButtonState(0);
+  touch_status = touchpad->ButtonState(VirtualTouchpad::PRIMARY, 0);
   EXPECT_EQ(0, touch_status);
   expect.WriteInputEvent(EV_KEY, BTN_BACK, EvdevInjector::KEY_RELEASE);
   expect.WriteInputEvent(EV_SYN, SYN_REPORT, 0);
@@ -226,20 +230,21 @@
   UInputRecorder expect;
   UInputRecorder record;
   EvdevInjectorForTesting injector(record);
-  sp<VirtualTouchpad> touchpad(
-      VirtualTouchpadForTesting::Create(injector));
+  sp<VirtualTouchpad> touchpad(VirtualTouchpadForTesting::Create(injector));
 
   // Touch off-screen should return an error,
   // and should not result in any system calls.
   expect.Reset();
   record.Reset();
-  status_t touch_status = touchpad->Touch(-0.25f, 0.75f, 1.0f);
+  status_t touch_status =
+      touchpad->Touch(VirtualTouchpad::PRIMARY, -0.25f, 0.75f, 1.0f);
   EXPECT_NE(OK, touch_status);
-  touch_status = touchpad->Touch(0.25f, -0.75f, 1.0f);
+  touch_status =
+      touchpad->Touch(VirtualTouchpad::PRIMARY, 0.25f, -0.75f, 1.0f);
   EXPECT_NE(OK, touch_status);
-  touch_status = touchpad->Touch(1.25f, 0.75f, 1.0f);
+  touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 1.25f, 0.75f, 1.0f);
   EXPECT_NE(OK, touch_status);
-  touch_status = touchpad->Touch(0.25f, 1.75f, 1.0f);
+  touch_status = touchpad->Touch(VirtualTouchpad::PRIMARY, 0.25f, 1.75f, 1.0f);
   EXPECT_NE(OK, touch_status);
   EXPECT_EQ(expect.GetString(), record.GetString());
 
@@ -247,7 +252,8 @@
   // and should not result in any system calls.
   expect.Reset();
   record.Reset();
-  touch_status = touchpad->ButtonState(AMOTION_EVENT_BUTTON_FORWARD);
+  touch_status = touchpad->ButtonState(VirtualTouchpad::PRIMARY,
+                                       AMOTION_EVENT_BUTTON_FORWARD);
   EXPECT_NE(OK, touch_status);
   EXPECT_EQ(expect.GetString(), record.GetString());
 }
diff --git a/services/vr/vr_window_manager/shell_view.cpp b/services/vr/vr_window_manager/shell_view.cpp
index 7321ed0..fae1dd9 100644
--- a/services/vr/vr_window_manager/shell_view.cpp
+++ b/services/vr/vr_window_manager/shell_view.cpp
@@ -721,6 +721,7 @@
   }
 
   const android::status_t status = virtual_touchpad_->Touch(
+      VirtualTouchpad::PRIMARY,
       hit_location_in_window_coord_.x() / size_.x(),
       hit_location_in_window_coord_.y() / size_.y(),
       is_touching_ ? 1.0f : 0.0f);
@@ -747,8 +748,8 @@
     return false;
   }
 
-  const android::status_t status =
-      virtual_touchpad_->ButtonState(touchpad_buttons_);
+  const android::status_t status = virtual_touchpad_->ButtonState(
+      VirtualTouchpad::PRIMARY, touchpad_buttons_);
   if (status != OK) {
     ALOGE("touchpad button failed: %d %d", touchpad_buttons_, status);
   }