Merge "Create libhwc2on1adapter"
diff --git a/cmds/installd/tests/installd_utils_test.cpp b/cmds/installd/tests/installd_utils_test.cpp
index 6a8755e..93a1458 100644
--- a/cmds/installd/tests/installd_utils_test.cpp
+++ b/cmds/installd/tests/installd_utils_test.cpp
@@ -334,19 +334,6 @@
              << "Package path should be a really long string of a's";
 }
 
-TEST_F(UtilsTest, CreatePkgPath_LongPkgNameFail) {
-    char path[PKG_PATH_MAX];
-
-    // Create long packagename of "aaaaa..."
-    size_t pkgnameSize = PKG_NAME_MAX + 1;
-    char pkgname[pkgnameSize + 1];
-    memset(pkgname, 'a', pkgnameSize);
-    pkgname[pkgnameSize] = '\0';
-
-    EXPECT_EQ(-1, create_pkg_path(path, pkgname, "", 0))
-            << "Should return error because package name is too long.";
-}
-
 TEST_F(UtilsTest, CreatePkgPath_LongPostfixFail) {
     char path[PKG_PATH_MAX];
 
@@ -514,6 +501,7 @@
 }
 
 TEST_F(UtilsTest, IsValidPackageName) {
+    EXPECT_EQ(true, is_valid_package_name("android"));
     EXPECT_EQ(true, is_valid_package_name("com.example"));
     EXPECT_EQ(true, is_valid_package_name("com.example-1"));
     EXPECT_EQ(true, is_valid_package_name("com.example-1024"));
@@ -522,9 +510,10 @@
 
     EXPECT_EQ(false, is_valid_package_name("1234.package"));
     EXPECT_EQ(false, is_valid_package_name("com.1234.package"));
-    EXPECT_EQ(false, is_valid_package_name("package"));
     EXPECT_EQ(false, is_valid_package_name(""));
     EXPECT_EQ(false, is_valid_package_name("."));
+    EXPECT_EQ(false, is_valid_package_name(".."));
+    EXPECT_EQ(false, is_valid_package_name("../"));
     EXPECT_EQ(false, is_valid_package_name("com.example/../com.evil/"));
     EXPECT_EQ(false, is_valid_package_name("com.example-1/../com.evil/"));
     EXPECT_EQ(false, is_valid_package_name("/com.evil"));
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index b379037..af7a7c6 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -375,7 +375,7 @@
         return false;
     }
 
-    if (!hasSep || front) {
+    if (front) {
         LOG(WARNING) << "Missing separator in " << packageName;
         return false;
     }
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index 9e60461..8750147 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -160,14 +160,14 @@
 }
 
 void Lshal::forEachTable(const std::function<void(Table &)> &f) {
-    for (const Table &table : {mServicesTable, mPassthroughRefTable, mImplementationsTable}) {
-        f(const_cast<Table &>(table));
-    }
+    f(mServicesTable);
+    f(mPassthroughRefTable);
+    f(mImplementationsTable);
 }
 void Lshal::forEachTable(const std::function<void(const Table &)> &f) const {
-    for (const Table &table : {mServicesTable, mPassthroughRefTable, mImplementationsTable}) {
-        f(table);
-    }
+    f(mServicesTable);
+    f(mPassthroughRefTable);
+    f(mImplementationsTable);
 }
 
 void Lshal::postprocess() {
@@ -183,6 +183,26 @@
             }
         }
     });
+    // use a double for loop here because lshal doesn't care about efficiency.
+    for (TableEntry &packageEntry : mImplementationsTable) {
+        std::string packageName = packageEntry.interfaceName;
+        FQName fqPackageName{packageName.substr(0, packageName.find("::"))};
+        if (!fqPackageName.isValid()) {
+            continue;
+        }
+        for (TableEntry &interfaceEntry : mPassthroughRefTable) {
+            if (interfaceEntry.arch != ARCH_UNKNOWN) {
+                continue;
+            }
+            FQName interfaceName{splitFirst(interfaceEntry.interfaceName, '/').first};
+            if (!interfaceName.isValid()) {
+                continue;
+            }
+            if (interfaceName.getPackageAndVersion() == fqPackageName) {
+                interfaceEntry.arch = packageEntry.arch;
+            }
+        }
+    }
 }
 
 void Lshal::printLine(
@@ -247,10 +267,25 @@
                     &table == &mImplementationsTable ? "" : splittedFqInstanceName.second;
 
             vintf::Transport transport;
+            vintf::Arch arch;
             if (entry.transport == "hwbinder") {
                 transport = vintf::Transport::HWBINDER;
+                arch = vintf::Arch::ARCH_EMPTY;
             } else if (entry.transport == "passthrough") {
                 transport = vintf::Transport::PASSTHROUGH;
+                switch (entry.arch) {
+                    case lshal::ARCH32:
+                        arch = vintf::Arch::ARCH_32;    break;
+                    case lshal::ARCH64:
+                        arch = vintf::Arch::ARCH_64;    break;
+                    case lshal::ARCH_BOTH:
+                        arch = vintf::Arch::ARCH_32_64; break;
+                    case lshal::ARCH_UNKNOWN: // fallthrough
+                    default:
+                        mErr << "Warning: '" << fqName.package()
+                             << "' doesn't have bitness info, assuming 32+64." << std::endl;
+                        arch = vintf::Arch::ARCH_32_64;
+                }
             } else {
                 mErr << "Warning: '" << entry.transport << "' is not a valid transport." << std::endl;
                 continue;
@@ -262,7 +297,7 @@
                     .format = vintf::HalFormat::HIDL,
                     .name = fqName.package(),
                     .impl = {.implLevel = vintf::ImplLevel::GENERIC, .impl = ""},
-                    .transport = transport
+                    .transportArch = {transport, arch}
                 })) {
                     mErr << "Warning: cannot add hal '" << fqInstanceName << "'" << std::endl;
                     continue;
diff --git a/cmds/lshal/TableEntry.h b/cmds/lshal/TableEntry.h
index 2407b42..9ae8f78 100644
--- a/cmds/lshal/TableEntry.h
+++ b/cmds/lshal/TableEntry.h
@@ -37,8 +37,8 @@
 
 enum : unsigned int {
     ARCH_UNKNOWN = 0,
-    ARCH64       = 1 << 0,
-    ARCH32       = 1 << 1,
+    ARCH32       = 1 << 0,
+    ARCH64       = 1 << 1,
     ARCH_BOTH    = ARCH32 | ARCH64
 };
 using Architecture = unsigned int;
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index ad1984a..a2e12f7 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -836,6 +836,10 @@
                 *value = mFrameTimestampsSupportsRetire ? 1 : 0;
                 return NO_ERROR;
             }
+            case NATIVE_WINDOW_IS_VALID: {
+                *value = mGraphicBufferProducer != nullptr ? 1 : 0;
+                return NO_ERROR;
+            }
         }
     }
     return mGraphicBufferProducer->query(what, value);
diff --git a/libs/vr/libdvrcommon/include/private/dvr/matrix_helpers.h b/libs/vr/libdvrcommon/include/private/dvr/matrix_helpers.h
new file mode 100644
index 0000000..aef7146
--- /dev/null
+++ b/libs/vr/libdvrcommon/include/private/dvr/matrix_helpers.h
@@ -0,0 +1,26 @@
+#ifndef ANDROID_DVR_MATRIX_HELPERS_H_
+#define ANDROID_DVR_MATRIX_HELPERS_H_
+
+#include <private/dvr/eigen.h>
+#include <private/dvr/types.h>
+
+namespace android {
+namespace dvr {
+
+// A helper function for creating a mat4 directly.
+inline mat4 MakeMat4(float m00, float m01, float m02, float m03, float m10,
+                     float m11, float m12, float m13, float m20, float m21,
+                     float m22, float m23, float m30, float m31, float m32,
+                     float m33) {
+  Eigen::Matrix4f matrix;
+
+  matrix << m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30,
+      m31, m32, m33;
+
+  return mat4(matrix);
+}
+
+}  // namespace dvr
+}  // namespace android
+
+#endif  // ANDROID_DVR_LOG_HELPERS_H_
diff --git a/libs/vr/libdvrcommon/include/private/dvr/numeric.h b/libs/vr/libdvrcommon/include/private/dvr/numeric.h
index 584236a..4545893 100644
--- a/libs/vr/libdvrcommon/include/private/dvr/numeric.h
+++ b/libs/vr/libdvrcommon/include/private/dvr/numeric.h
@@ -126,12 +126,9 @@
 Derived1 RandomInRange(
     const Eigen::MatrixBase<Derived1>& lo,
     const Eigen::MatrixBase<Derived2>& hi) {
-  using Matrix1_t = Eigen::MatrixBase<Derived1>;
-  using Matrix2_t = Eigen::MatrixBase<Derived2>;
+  EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived1, Derived2);
 
-  EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Matrix1_t, Matrix2_t);
-
-  Derived1 result = Matrix1_t::Zero();
+  Derived1 result = Eigen::MatrixBase<Derived1>::Zero();
 
   for (int row = 0; row < result.rows(); ++row) {
     for (int col = 0; col < result.cols(); ++col) {
diff --git a/libs/vr/libdvrcommon/tests/numeric_test.cpp b/libs/vr/libdvrcommon/tests/numeric_test.cpp
index a6a2182..1ee1447 100644
--- a/libs/vr/libdvrcommon/tests/numeric_test.cpp
+++ b/libs/vr/libdvrcommon/tests/numeric_test.cpp
@@ -1,6 +1,5 @@
 #include <gtest/gtest.h>
 
-#define EIGEN_NO_STATIC_ASSERT
 #include <private/dvr/numeric.h>
 
 using TestTypes = ::testing::Types<float, double, int>;
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index e52713f..aed27c8 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -478,6 +478,16 @@
     if (dp) {
         EGLDisplay iDpy = dp->disp.dpy;
 
+        if (!window) {
+            return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+        }
+
+        int value = 0;
+        window->query(window, NATIVE_WINDOW_IS_VALID, &value);
+        if (!value) {
+            return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+        }
+
         int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
         if (result != OK) {
             ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) "
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index e2b2a3a..0efdf54 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -707,7 +707,7 @@
 
     // A layer can be attached to multiple displays when operating in mirror mode
     // (a.k.a: when several displays are attached with equal layerStack). In this
-    // case we need to keep track. In non-mirror mode, a layer will have only one.
+    // case we need to keep track. In non-mirror mode, a layer will have only one
     // HWCInfo. This map key is a display layerStack.
     std::unordered_map<int32_t, HWCInfo> mHwcLayers;
 
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);
   }