| #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 |