Revise virtual touchpad interface.

- Explicit start and stop, outside of which the evdev devices
  don't exist.
- Permission test (not compiled by default pending build & SELinux
  support for temporarily retaining a second copy of the service
  for vr_wm).
- Enforce a single user of the touchpad.
- Support 'dumpsys'.

Bug: 36051900
Test: log inspection
Change-Id: I038ed2632d5adf50a3565a981031691d5dc5f7cd
diff --git a/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp b/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp
index 175173f..782b19c 100644
--- a/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp
+++ b/services/vr/virtual_touchpad/VirtualTouchpadClient.cpp
@@ -10,17 +10,49 @@
 
 class VirtualTouchpadClientImpl : public VirtualTouchpadClient {
  public:
-  VirtualTouchpadClientImpl(sp<IVirtualTouchpadService> service)
-      : service_(service) {}
-  ~VirtualTouchpadClientImpl() override {}
+  VirtualTouchpadClientImpl() {}
+  ~VirtualTouchpadClientImpl() override {
+    if (service_ != nullptr) {
+      Detach();
+    }
+  }
 
-  status_t Touch(int touchpad,
-                 float x, float y, float pressure) override {
+  status_t Attach() {
+    if (service_ != nullptr) {
+      return ALREADY_EXISTS;
+    }
+    sp<IServiceManager> sm = defaultServiceManager();
+    if (sm == nullptr) {
+      ALOGE("no service manager");
+      return NO_INIT;
+    }
+    sp<IVirtualTouchpadService> service =
+        interface_cast<IVirtualTouchpadService>(
+            sm->getService(IVirtualTouchpadService::SERVICE_NAME()));
+    if (service == nullptr) {
+      ALOGE("failed to get service");
+      return NAME_NOT_FOUND;
+    }
+    service_ = service;
+    return service_->attach().transactionError();
+  }
+
+  status_t Detach() {
+    if (service_ == nullptr) {
+      return NO_INIT;
+    }
+    status_t status = service_->detach().transactionError();
+    service_ = nullptr;
+    return status;
+  }
+
+  status_t Touch(int touchpad, float x, float y, float pressure) override {
     if (service_ == nullptr) {
       return NO_INIT;
     }
     return service_->touch(touchpad, x, y, pressure).transactionError();
   }
+
   status_t ButtonState(int touchpad, int buttons) override {
     if (service_ == nullptr) {
       return NO_INIT;
@@ -28,6 +60,12 @@
     return service_->buttonState(touchpad, buttons).transactionError();
   }
 
+  void dumpInternal(String8& result) override {
+    result.append("[virtual touchpad]\n");
+    result.appendFormat("connected = %s\n\n",
+                        service_ != nullptr ? "true" : "false");
+  }
+
  private:
   sp<IVirtualTouchpadService> service_;
 };
@@ -35,18 +73,7 @@
 }  // anonymous namespace
 
 sp<VirtualTouchpad> VirtualTouchpadClient::Create() {
-  sp<IServiceManager> sm = defaultServiceManager();
-  if (sm == nullptr) {
-    ALOGE("no service manager");
-    return sp<VirtualTouchpad>();
-  }
-  sp<IVirtualTouchpadService> service = interface_cast<IVirtualTouchpadService>(
-      sm->getService(IVirtualTouchpadService::SERVICE_NAME()));
-  if (service == nullptr) {
-    ALOGE("failed to get service");
-    return sp<VirtualTouchpad>();
-  }
-  return new VirtualTouchpadClientImpl(service);
+  return new VirtualTouchpadClientImpl();
 }
 
 }  // namespace dvr