Merge "Vibrates using 'cmd vibrator' instead of HAL vibrator."
diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp
index 01a2fa3..a596a67 100644
--- a/cmds/dumpsys/tests/dumpsys_test.cpp
+++ b/cmds/dumpsys/tests/dumpsys_test.cpp
@@ -79,6 +79,8 @@
                 const hidl_string&,
                 const sp<IServiceNotification>&));
     MOCK_METHOD1(debugDump, R<void>(debugDump_cb));
+    MOCK_METHOD3(registerPassthroughClient, R<void>(
+        const hidl_string&, const hidl_string&, int32_t));
 
 };
 
diff --git a/cmds/lshal/lshal.cpp b/cmds/lshal/lshal.cpp
index bc5eaf2..9998a46 100644
--- a/cmds/lshal/lshal.cpp
+++ b/cmds/lshal/lshal.cpp
@@ -28,31 +28,60 @@
 #include <android/hidl/manager/1.0/IServiceManager.h>
 #include <hidl/ServiceManagement.h>
 
-template <typename A, typename B, typename C, typename D, typename E>
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hidl::manager::V1_0::IServiceManager;
+
+template <typename A, typename B, typename C, typename D, typename E, typename F>
 void printColumn(std::stringstream &stream,
-        const A &a, const B &b, const C &c, const D &d, const E &e) {
+        const A &a, const B &b, const C &c, const D &d, const E &, const F &f) {
     using namespace ::std;
     stream << left
            << setw(70) << a << "\t"
            << setw(20) << b << "\t"
            << setw(10) << c << "\t"
            << setw(5)  << d << "\t"
-           << setw(0)  << e
+           // TODO(b/34984175): enable selecting columns
+           // << setw(16) << e << "\t"
+           << setw(0)  << f
            << endl;
 }
 
+template <typename A>
+std::string join(const A &components, const std::string &separator) {
+    std::stringstream out;
+    bool first = true;
+    for (const auto &component : components) {
+        if (!first) {
+            out << separator;
+        }
+        out << component;
+
+        first = false;
+    }
+    return out.str();
+}
+
 std::string toHexString(uint64_t t) {
     std::ostringstream os;
     os << std::hex << std::setfill('0') << std::setw(16) << t;
     return os.str();
 }
 
-::android::status_t getReferencedPids(
+std::pair<hidl_string, hidl_string> split(const hidl_string &s, char c) {
+    const char *pos = strchr(s.c_str(), c);
+    if (pos == nullptr) {
+        return {s, {}};
+    }
+    return {hidl_string(s.c_str(), pos - s.c_str()), hidl_string(pos + 1)};
+}
+
+bool getReferencedPids(
         pid_t serverPid, std::map<uint64_t, std::string> *objects) {
 
     std::ifstream ifs("/d/binder/proc/" + std::to_string(serverPid));
     if (!ifs.is_open()) {
-        return ::android::PERMISSION_DENIED;
+        return false;
     }
 
     static const std::regex prefix("^\\s*node \\d+:\\s+u([0-9a-f]+)\\s+c([0-9a-f]+)\\s+");
@@ -77,66 +106,165 @@
             (*objects)[ptr] += line.substr(pos + proc.size());
         }
     }
-    return ::android::OK;
+    return true;
 }
 
+void dumpAllLibraries(std::stringstream &stream, const std::string &mode,
+            const sp<IServiceManager> &manager) {
+    using namespace ::std;
+    using namespace ::android::hardware;
+    using namespace ::android::hidl::manager::V1_0;
+    using namespace ::android::hidl::base::V1_0;
+    auto ret = manager->list([&] (const auto &fqInstanceNames) {
+        for (const auto &fqInstanceName : fqInstanceNames) {
+            const auto pair = split(fqInstanceName, '/');
+            const auto &serviceName = pair.first;
+            const auto &instanceName = pair.second;
+            printColumn(stream,
+                serviceName,
+                instanceName,
+                mode,
+                "N/A",
+                "N/A",
+                "N/A");
+        }
+    });
+    if (!ret.isOk()) {
+        cerr << "Error: Failed to call debugDump on defaultServiceManager(): "
+             << ret.description() << endl;
+    }
+}
+
+void dumpPassthrough(std::stringstream &stream, const std::string &mode,
+            const sp<IServiceManager> &manager) {
+    using namespace ::std;
+    using namespace ::android::hardware;
+    using namespace ::android::hidl::manager::V1_0;
+    using namespace ::android::hidl::base::V1_0;
+    auto ret = manager->debugDump([&] (const auto &infos) {
+        for (const auto &info : infos) {
+
+            printColumn(stream,
+                info.interfaceName,
+                info.instanceName,
+                mode,
+                info.clientPids.size() == 1 ? std::to_string(info.clientPids[0]) : "N/A",
+                "N/A",
+                join(info.clientPids, " "));
+        }
+    });
+    if (!ret.isOk()) {
+        cerr << "Error: Failed to call debugDump on defaultServiceManager(): "
+             << ret.description() << endl;
+    }
+}
+
+void dumpBinderized(std::stringstream &stream, const std::string &mode,
+            const sp<IServiceManager> &manager) {
+    using namespace ::std;
+    using namespace ::android::hardware;
+    using namespace ::android::hidl::manager::V1_0;
+    using namespace ::android::hidl::base::V1_0;
+    auto listRet = manager->list([&] (const auto &fqInstanceNames) {
+        // server pid, .ptr value of binder object, child pids
+        std::map<std::string, DebugInfo> allDebugInfos;
+        std::map<pid_t, std::map<uint64_t, std::string>> allPids;
+        for (const auto &fqInstanceName : fqInstanceNames) {
+            const auto pair = split(fqInstanceName, '/');
+            const auto &serviceName = pair.first;
+            const auto &instanceName = pair.second;
+            auto getRet = manager->get(serviceName, instanceName);
+            if (!getRet.isOk()) {
+                cerr << "Warning: Skipping \"" << fqInstanceName << "\": "
+                     << "cannot be fetched from service manager:"
+                     << getRet.description() << endl;
+                continue;
+            }
+            sp<IBase> service = getRet;
+            if (service == nullptr) {
+                cerr << "Warning: Skipping \"" << fqInstanceName << "\": "
+                     << "cannot be fetched from service manager (null)";
+                continue;
+            }
+            auto debugRet = service->getDebugInfo([&] (const auto &debugInfo) {
+                allDebugInfos[fqInstanceName] = debugInfo;
+                if (debugInfo.pid >= 0) {
+                    allPids[static_cast<pid_t>(debugInfo.pid)].clear();
+                }
+            });
+            if (!debugRet.isOk()) {
+                cerr << "Warning: Skipping \"" << fqInstanceName << "\": "
+                     << "debugging information cannot be retrieved:"
+                     << debugRet.description() << endl;
+            }
+        }
+        for (auto &pair : allPids) {
+            pid_t serverPid = pair.first;
+            if (!getReferencedPids(serverPid, &allPids[serverPid])) {
+                std::cerr << "Warning: no information for PID " << serverPid
+                          << ", are you root?" << std::endl;
+            }
+        }
+        for (const auto &fqInstanceName : fqInstanceNames) {
+            const auto pair = split(fqInstanceName, '/');
+            const auto &serviceName = pair.first;
+            const auto &instanceName = pair.second;
+            auto it = allDebugInfos.find(fqInstanceName);
+            if (it == allDebugInfos.end()) {
+                printColumn(stream,
+                    serviceName,
+                    instanceName,
+                    mode,
+                    "N/A",
+                    "N/A",
+                    ""
+                );
+                continue;
+            }
+            const DebugInfo &info = it->second;
+            printColumn(stream,
+                serviceName,
+                instanceName,
+                mode,
+                info.pid < 0 ? "N/A" : std::to_string(info.pid),
+                info.ptr == 0 ? "N/A" : toHexString(info.ptr),
+                info.pid < 0 || info.ptr == 0 ? "" : allPids[info.pid][info.ptr]
+            );
+        }
+
+    });
+    if (!listRet.isOk()) {
+        cerr << "Error: Failed to list services for " << mode << ": "
+             << listRet.description() << endl;
+    }
+}
 
 int dump() {
     using namespace ::std;
     using namespace ::android::hardware;
-    using namespace ::android::hidl::manager::V1_0;
-
-    std::map<std::string, ::android::sp<IServiceManager>> mapping = {
-            {"hwbinder", defaultServiceManager()},
-            {"passthrough", getPassthroughServiceManager()}
-    };
 
     std::stringstream stream;
 
     stream << "All services:" << endl;
     stream << left;
-    printColumn(stream, "Interface", "Instance", "Transport", "Server", "Clients");
+    printColumn(stream, "Interface", "Instance", "Transport", "Server", "PTR", "Clients");
 
-    for (const auto &pair : mapping) {
-        const std::string &mode = pair.first;
-        const ::android::sp<IServiceManager> &manager = pair.second;
-
-        if (manager == nullptr) {
-            cerr << "Failed to get IServiceManager for " << mode << "!" << endl;
-            continue;
-        }
-
-        auto ret = manager->debugDump([&](const auto &registered) {
-            // server pid, .ptr value of binder object, child pids
-            std::map<pid_t, std::map<uint64_t, std::string>> allPids;
-            for (const auto &info : registered) {
-                if (info.pid < 0) {
-                    continue;
-                }
-                pid_t serverPid = info.pid;
-                allPids[serverPid].clear();
-            }
-            for (auto &pair : allPids) {
-                pid_t serverPid = pair.first;
-                if (getReferencedPids(serverPid, &allPids[serverPid]) != ::android::OK) {
-                    std::cerr << "Warning: no information for PID " << serverPid
-                              << ", are you root?" << std::endl;
-                }
-            }
-            for (const auto &info : registered) {
-                printColumn(stream,
-                    info.interfaceName,
-                    info.instanceName.empty() ? "N/A" : info.instanceName,
-                    mode,
-                    info.pid < 0 ? "N/A" : std::to_string(info.pid),
-                    info.pid < 0 || info.ptr == 0 ? "" : allPids[info.pid][info.ptr]);
-            }
-        });
-        if (!ret.isOk()) {
-            cerr << "Failed to list services for " << mode << ": "
-                 << ret.description() << endl;
-        }
+    auto bManager = defaultServiceManager();
+    if (bManager == nullptr) {
+        cerr << "Failed to get defaultServiceManager()!" << endl;
+    } else {
+        dumpBinderized(stream, "hwbinder", bManager);
+        // Passthrough PIDs are registered to the binderized manager as well.
+        dumpPassthrough(stream, "passthrough", bManager);
     }
+
+    auto pManager = getPassthroughServiceManager();
+    if (pManager == nullptr) {
+        cerr << "Failed to get getPassthroughServiceManager()!" << endl;
+    } else {
+        dumpAllLibraries(stream, "passthrough", pManager);
+    }
+
     cout << stream.rdbuf();
     return 0;
 }
diff --git a/include/gui/GraphicBufferAlloc.h b/include/gui/GraphicBufferAlloc.h
index 9e18907..54c9829 100644
--- a/include/gui/GraphicBufferAlloc.h
+++ b/include/gui/GraphicBufferAlloc.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H
-#define ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H
+#ifndef ANDROID_GUI_GRAPHIC_BUFFER_ALLOC_H
+#define ANDROID_GUI_GRAPHIC_BUFFER_ALLOC_H
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -25,10 +25,16 @@
 #include <utils/Errors.h>
 
 namespace android {
-// ---------------------------------------------------------------------------
 
 class GraphicBuffer;
 
+/*
+ * Concrete implementation of the IGraphicBufferAlloc interface.
+ *
+ * This can create GraphicBuffer instance across processes. This is mainly used
+ * by surfaceflinger.
+ */
+
 class GraphicBufferAlloc : public BnGraphicBufferAlloc {
 public:
     GraphicBufferAlloc();
@@ -40,7 +46,6 @@
 };
 
 
-// ---------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
 
-#endif // ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H
+#endif // ANDROID_GUI_GRAPHIC_BUFFER_ALLOC_H
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 95ca0f3..759c9ec 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -76,11 +76,6 @@
     GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
             uint32_t inUsage, std::string requestorName = "<Unknown>");
 
-    // creates w * h buffer with a layer count
-    GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
-            uint32_t inLayerCount, uint32_t inUsage,
-            std::string requestorName = "<Unknown>");
-
     // creates w * h buffer with a layer count using gralloc1
     GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
             uint32_t inLayerCount, uint64_t inProducerUsage,
diff --git a/include/ui/GraphicBufferMapper.h b/include/ui/GraphicBufferMapper.h
index 8e93f72..001769f 100644
--- a/include/ui/GraphicBufferMapper.h
+++ b/include/ui/GraphicBufferMapper.h
@@ -39,7 +39,9 @@
 public:
     static inline GraphicBufferMapper& get() { return getInstance(); }
 
+    // This may NOT work on devices without a valid Gralloc2::Mapper.
     status_t registerBuffer(buffer_handle_t handle);
+
     status_t registerBuffer(const GraphicBuffer* buffer);
 
     status_t unregisterBuffer(buffer_handle_t handle);
diff --git a/libs/gui/GraphicBufferAlloc.cpp b/libs/gui/GraphicBufferAlloc.cpp
index f2d3677..cc7d403 100644
--- a/libs/gui/GraphicBufferAlloc.cpp
+++ b/libs/gui/GraphicBufferAlloc.cpp
@@ -15,21 +15,15 @@
  ** limitations under the License.
  */
 
-#include <log/log.h>
-
-#include <ui/GraphicBuffer.h>
-
 #include <gui/GraphicBufferAlloc.h>
 
-// ----------------------------------------------------------------------------
+#include <log/log.h>
+
+
 namespace android {
-// ----------------------------------------------------------------------------
 
-GraphicBufferAlloc::GraphicBufferAlloc() {
-}
-
-GraphicBufferAlloc::~GraphicBufferAlloc() {
-}
+GraphicBufferAlloc::GraphicBufferAlloc() = default;
+GraphicBufferAlloc::~GraphicBufferAlloc() = default;
 
 sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t width,
         uint32_t height, PixelFormat format, uint32_t layerCount,
@@ -44,15 +38,12 @@
         if (err == NO_MEMORY) {
             GraphicBuffer::dumpAllocationsToSystemLog();
         }
-        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%u, h=%u, lc=%u) "
-             "failed (%s), handle=%p",
+        ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%u, h=%u, lc=%u) failed (%s), handle=%p",
                 width, height, layerCount, strerror(-err),
                 graphicBuffer->handle);
-        return 0;
+        graphicBuffer.clear();
     }
     return graphicBuffer;
 }
 
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
+} // namespace android
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 5ef95ec..b544426 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -50,8 +50,8 @@
     height =
     stride =
     format =
-    layerCount =
     usage  = 0;
+    layerCount = 0;
     handle = NULL;
 }
 
@@ -64,8 +64,8 @@
     height =
     stride =
     format =
-    layerCount =
     usage  = 0;
+    layerCount = 0;
     handle = NULL;
     mInitCheck = initSize(inWidth, inHeight, inFormat, 1, inUsage, inUsage,
             std::move(requestorName));
@@ -81,8 +81,8 @@
     height =
     stride =
     format =
-    layerCount =
     usage  = 0;
+    layerCount = 0;
     handle = NULL;
     mInitCheck = initSize(inWidth, inHeight, inFormat, inLayerCount,
             producerUsage, consumerUsage, std::move(requestorName));
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index b0ed2df..a3b6e18 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -63,7 +63,14 @@
     if (mMapper->valid()) {
         error = static_cast<gralloc1_error_t>(mMapper->retain(handle));
     } else {
+        // This always returns GRALLOC1_BAD_HANDLE when handle is from a
+        // remote process and mDevice is backed by Gralloc1On0Adapter.
         error = mDevice->retain(handle);
+        if (error == GRALLOC1_ERROR_BAD_HANDLE &&
+                mDevice->hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
+            ALOGE("registerBuffer by handle is not supported with "
+                  "Gralloc1On0Adapter");
+        }
     }
 
     ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
diff --git a/services/vr/vr_manager/Android.mk b/libs/vr/libvr_manager/Android.mk
similarity index 79%
rename from services/vr/vr_manager/Android.mk
rename to libs/vr/libvr_manager/Android.mk
index 54b1c1a..e9987f7 100644
--- a/services/vr/vr_manager/Android.mk
+++ b/libs/vr/libvr_manager/Android.mk
@@ -14,11 +14,16 @@
 
 LOCAL_PATH := $(call my-dir)
 
+exported_include_dirs := \
+  $(LOCAL_PATH)/include
+
+include_dirs := \
+  frameworks/native/include/vr/vr_manager \
+  $(exported_include_dirs)
+
 src_files := \
   vr_manager.cpp \
-
-inc_files := \
-  frameworks/native/include/vr/vr_manager
+  trusted_uids.cpp
 
 static_libs := \
   libutils \
@@ -26,13 +31,12 @@
 
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := $(src_files)
-LOCAL_C_INCLUDES := $(inc_files)
+LOCAL_C_INCLUDES := $(include_dirs)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(exported_include_dirs)
 LOCAL_CFLAGS += -Wall
 LOCAL_CFLAGS += -Werror
 LOCAL_CFLAGS += -Wunused
 LOCAL_CFLAGS += -Wunreachable-code
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(inc_files)
-#LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
 LOCAL_STATIC_LIBRARIES := $(static_libs)
 LOCAL_MODULE := libvr_manager
 include $(BUILD_STATIC_LIBRARY)
diff --git a/libs/vr/libvr_manager/include/private/dvr/trusted_uids.h b/libs/vr/libvr_manager/include/private/dvr/trusted_uids.h
new file mode 100644
index 0000000..4496fbf
--- /dev/null
+++ b/libs/vr/libvr_manager/include/private/dvr/trusted_uids.h
@@ -0,0 +1,33 @@
+#ifndef ANDROID_DVR_TRUSTED_UIDS_H_
+#define ANDROID_DVR_TRUSTED_UIDS_H_
+
+#include <sys/types.h>
+
+namespace android {
+namespace dvr {
+
+/**
+ * Tells if a provided UID can be trusted to access restricted VR APIs.
+ *
+ * UID trust is based on the android.permission.RESTRICTED_VR_ACCESS permission.
+ * AID_SYSTEM and AID_ROOT are automatically trusted by Android.
+ *
+ * UIDs are guaranteed not to be reused until the next reboot even in case
+ * of package reinstall. For performance reasons this method caches results by
+ * default, as otherwise every check would trigger a Java call.
+ *
+ * This function is thread-safe.
+ *
+ * @param uid The uid to check.
+ * @param use_cache If true any cached result for the provided uid will be
+ *     reused. If false this call will reach the Application Manager Service
+ *     in Java to get updated values. Any updates will be stored in the cache.
+ * @return true if the uid is trusted, false if not or if the VR Manager Service
+ *         could not be reached to verify the uid.
+ */
+bool IsTrustedUid(uid_t uid, bool use_cache = true);
+
+}  // namespace dvr
+}  // namespace android
+
+#endif  // ANDROID_DVR_TRUSTED_UIDS_H_
diff --git a/libs/vr/libvr_manager/trusted_uids.cpp b/libs/vr/libvr_manager/trusted_uids.cpp
new file mode 100644
index 0000000..4228a05
--- /dev/null
+++ b/libs/vr/libvr_manager/trusted_uids.cpp
@@ -0,0 +1,51 @@
+#include "private/dvr/trusted_uids.h"
+
+#include <mutex>
+#include <unordered_map>
+
+#include <binder/IPermissionController.h>
+#include <binder/IServiceManager.h>
+#include <private/android_filesystem_config.h>
+#include <utils/String16.h>
+#include <vr/vr_manager/vr_manager.h>
+
+namespace android {
+namespace dvr {
+
+bool IsTrustedUid(uid_t uid, bool use_cache) {
+  static std::unordered_map<uid_t, bool> uid_cache;
+  static std::mutex uid_cache_mutex;
+
+  // Whitelist requests from the system UID.
+  // These are already whitelisted by the permission service, but it might not
+  // be available if the ActivityManagerService is up during boot.
+  // This ensures the correct result for system services while booting up.
+  if (uid == AID_SYSTEM)
+    return true;
+
+  std::lock_guard<std::mutex> lock(uid_cache_mutex);
+
+  if (use_cache) {
+    auto it = uid_cache.find(uid);
+    if (it != uid_cache.end())
+      return it->second;
+  }
+
+  sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
+  if (binder == 0) {
+    ALOGW("Could not access permission service");
+    return false;
+  }
+
+  // Note: we ignore the pid because it's only used to automatically reply
+  // true if the caller is the Activity Manager Service.
+  bool trusted = interface_cast<IPermissionController>(binder)->checkPermission(
+      String16("android.permission.RESTRICTED_VR_ACCESS"), -1, uid);
+
+  // Cache the information for this uid to avoid future Java calls.
+  uid_cache[uid] = trusted;
+  return trusted;
+}
+
+}  // namespace dvr
+}  // namespace android
diff --git a/services/vr/vr_manager/vr_manager.cpp b/libs/vr/libvr_manager/vr_manager.cpp
similarity index 100%
rename from services/vr/vr_manager/vr_manager.cpp
rename to libs/vr/libvr_manager/vr_manager.cpp
diff --git a/libs/vr/libvrflinger/Android.mk b/libs/vr/libvrflinger/Android.mk
index 6b5e7cc..d90e85a 100644
--- a/libs/vr/libvrflinger/Android.mk
+++ b/libs/vr/libvrflinger/Android.mk
@@ -45,6 +45,7 @@
 	libperformance \
 	libsensor \
 	libpdx_default_transport \
+	libvr_manager \
 
 sharedLibraries := \
 	android.dvr.composer@1.0 \
diff --git a/libs/vr/libvrflinger/screenshot_service.cpp b/libs/vr/libvrflinger/screenshot_service.cpp
index e174943..fd1c582 100644
--- a/libs/vr/libvrflinger/screenshot_service.cpp
+++ b/libs/vr/libvrflinger/screenshot_service.cpp
@@ -3,7 +3,9 @@
 #include <utils/Trace.h>
 
 #include <pdx/default_transport/service_endpoint.h>
+#include <private/android_filesystem_config.h>
 #include <private/dvr/display_types.h>
+#include <private/dvr/trusted_uids.h>
 
 using android::pdx::Message;
 using android::pdx::MessageInfo;
@@ -40,6 +42,12 @@
 
 ScreenshotData ScreenshotService::OnTakeScreenshot(pdx::Message& message,
                                                    int layer_index) {
+  // Also allow AID_SHELL to support vrscreencap commands.
+  if (message.GetEffectiveUserId() != AID_SHELL &&
+      !IsTrustedUid(message.GetEffectiveUserId())) {
+    REPLY_ERROR_RETURN(message, EACCES, {});
+  }
+
   AddWaiter(std::move(message), layer_index);
   return {};
 }