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 ®istered) {
- // 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 {};
}