86 lines
2.3 KiB
C++
86 lines
2.3 KiB
C++
#include "vr_composer.h"
|
|
|
|
#include <binder/IPCThreadState.h>
|
|
#include <binder/PermissionCache.h>
|
|
|
|
namespace android {
|
|
namespace dvr {
|
|
namespace {
|
|
|
|
bool CheckPermission() {
|
|
const android::IPCThreadState* ipc = android::IPCThreadState::self();
|
|
const pid_t pid = ipc->getCallingPid();
|
|
const uid_t uid = ipc->getCallingUid();
|
|
const bool permission = PermissionCache::checkPermission(
|
|
String16("android.permission.RESTRICTED_VR_ACCESS"), pid, uid);
|
|
if (!permission)
|
|
ALOGE("permission denied to pid=%d uid=%u", pid, uid);
|
|
|
|
return permission;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
VrComposer::VrComposer(ComposerView* composer_view)
|
|
: composer_view_(composer_view) {
|
|
composer_view_->RegisterObserver(this);
|
|
}
|
|
|
|
VrComposer::~VrComposer() {
|
|
composer_view_->UnregisterObserver(this);
|
|
}
|
|
|
|
binder::Status VrComposer::registerObserver(
|
|
const sp<IVrComposerCallback>& callback) {
|
|
{
|
|
std::lock_guard<std::mutex> guard(mutex_);
|
|
|
|
if (!CheckPermission())
|
|
return binder::Status::fromStatusT(PERMISSION_DENIED);
|
|
|
|
if (callback_.get()) {
|
|
ALOGE("Failed to register callback, already registered");
|
|
return binder::Status::fromStatusT(ALREADY_EXISTS);
|
|
}
|
|
|
|
callback_ = callback;
|
|
IInterface::asBinder(callback_)->linkToDeath(this);
|
|
}
|
|
|
|
// Don't take the lock to force display refresh otherwise it could end in a
|
|
// deadlock since HWC calls this with new frames and it has a lock of its own
|
|
// to serialize access to the display information.
|
|
composer_view_->ForceDisplaysRefresh();
|
|
return binder::Status::ok();
|
|
}
|
|
|
|
binder::Status VrComposer::clearObserver() {
|
|
std::lock_guard<std::mutex> guard(mutex_);
|
|
callback_ = nullptr;
|
|
return binder::Status::ok();
|
|
}
|
|
|
|
base::unique_fd VrComposer::OnNewFrame(const ComposerView::Frame& frame) {
|
|
std::lock_guard<std::mutex> guard(mutex_);
|
|
|
|
if (!callback_.get())
|
|
return base::unique_fd();
|
|
|
|
ParcelableComposerFrame parcelable_frame(frame);
|
|
ParcelableUniqueFd fence;
|
|
binder::Status ret = callback_->onNewFrame(parcelable_frame, &fence);
|
|
if (!ret.isOk())
|
|
ALOGE("Failed to send new frame: %s", ret.toString8().string());
|
|
|
|
return fence.fence();
|
|
}
|
|
|
|
void VrComposer::binderDied(const wp<IBinder>& /* who */) {
|
|
std::lock_guard<std::mutex> guard(mutex_);
|
|
|
|
callback_ = nullptr;
|
|
}
|
|
|
|
} // namespace dvr
|
|
} // namespace android
|