1 #include "vr_composer.h"
2 
3 #include <binder/IPCThreadState.h>
4 #include <binder/PermissionCache.h>
5 
6 namespace android {
7 namespace dvr {
8 namespace {
9 
CheckPermission()10 bool CheckPermission() {
11   const android::IPCThreadState* ipc = android::IPCThreadState::self();
12   const pid_t pid = ipc->getCallingPid();
13   const uid_t uid = ipc->getCallingUid();
14   const bool permission = PermissionCache::checkPermission(
15       String16("android.permission.RESTRICTED_VR_ACCESS"), pid, uid);
16   if (!permission)
17     ALOGE("permission denied to pid=%d uid=%u", pid, uid);
18 
19   return permission;
20 }
21 
22 }  // namespace
23 
VrComposer(ComposerView * composer_view)24 VrComposer::VrComposer(ComposerView* composer_view)
25   : composer_view_(composer_view) {
26   composer_view_->RegisterObserver(this);
27 }
28 
~VrComposer()29 VrComposer::~VrComposer() {
30   composer_view_->UnregisterObserver(this);
31 }
32 
registerObserver(const sp<IVrComposerCallback> & callback)33 binder::Status VrComposer::registerObserver(
34     const sp<IVrComposerCallback>& callback) {
35   {
36     std::lock_guard<std::mutex> guard(mutex_);
37 
38     if (!CheckPermission())
39       return binder::Status::fromStatusT(PERMISSION_DENIED);
40 
41     if (callback_.get()) {
42       ALOGE("Failed to register callback, already registered");
43       return binder::Status::fromStatusT(ALREADY_EXISTS);
44     }
45 
46     callback_ = callback;
47     IInterface::asBinder(callback_)->linkToDeath(this);
48   }
49 
50   // Don't take the lock to force display refresh otherwise it could end in a
51   // deadlock since HWC calls this with new frames and it has a lock of its own
52   // to serialize access to the display information.
53   composer_view_->ForceDisplaysRefresh();
54   return binder::Status::ok();
55 }
56 
clearObserver()57 binder::Status VrComposer::clearObserver() {
58   std::lock_guard<std::mutex> guard(mutex_);
59   callback_ = nullptr;
60   return binder::Status::ok();
61 }
62 
OnNewFrame(const ComposerView::Frame & frame)63 base::unique_fd VrComposer::OnNewFrame(const ComposerView::Frame& frame) {
64   std::lock_guard<std::mutex> guard(mutex_);
65 
66   if (!callback_.get())
67     return base::unique_fd();
68 
69   ParcelableComposerFrame parcelable_frame(frame);
70   ParcelableUniqueFd fence;
71   binder::Status ret = callback_->onNewFrame(parcelable_frame, &fence);
72   if (!ret.isOk())
73     ALOGE("Failed to send new frame: %s", ret.toString8().string());
74 
75   return fence.fence();
76 }
77 
binderDied(const wp<IBinder> &)78 void VrComposer::binderDied(const wp<IBinder>& /* who */) {
79   std::lock_guard<std::mutex> guard(mutex_);
80 
81   callback_ = nullptr;
82 }
83 
84 }  // namespace dvr
85 }  // namespace android
86