1aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara#include "vr_composer.h"
2aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara
30b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoara#include <binder/IPCThreadState.h>
40b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoara#include <binder/PermissionCache.h>
50b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoara
6aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoaranamespace android {
7aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoaranamespace dvr {
80b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoaranamespace {
90b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoara
100b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoarabool CheckPermission() {
110b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoara  const android::IPCThreadState* ipc = android::IPCThreadState::self();
120b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoara  const pid_t pid = ipc->getCallingPid();
130b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoara  const uid_t uid = ipc->getCallingUid();
140b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoara  const bool permission = PermissionCache::checkPermission(
150b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoara      String16("android.permission.RESTRICTED_VR_ACCESS"), pid, uid);
160b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoara  if (!permission)
170b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoara    ALOGE("permission denied to pid=%d uid=%u", pid, uid);
180b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoara
190b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoara  return permission;
200b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoara}
210b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoara
220b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoara}  // namespace
23aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara
248fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel NicoaraVrComposer::VrComposer(ComposerView* composer_view)
258fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara  : composer_view_(composer_view) {
268fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara  composer_view_->RegisterObserver(this);
278fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara}
28aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara
298fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel NicoaraVrComposer::~VrComposer() {
308fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara  composer_view_->UnregisterObserver(this);
318fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara}
32aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara
33aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoarabinder::Status VrComposer::registerObserver(
34aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara    const sp<IVrComposerCallback>& callback) {
358fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara  {
368fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara    std::lock_guard<std::mutex> guard(mutex_);
378fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara
388fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara    if (!CheckPermission())
398fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara      return binder::Status::fromStatusT(PERMISSION_DENIED);
40aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara
418fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara    if (callback_.get()) {
428fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara      ALOGE("Failed to register callback, already registered");
438fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara      return binder::Status::fromStatusT(ALREADY_EXISTS);
448fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara    }
450b4c80ac82959711738af326b6781f2a8e5ca542Daniel Nicoara
468fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara    callback_ = callback;
478fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara    IInterface::asBinder(callback_)->linkToDeath(this);
48aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara  }
49aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara
508fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara  // Don't take the lock to force display refresh otherwise it could end in a
518fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara  // deadlock since HWC calls this with new frames and it has a lock of its own
528fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara  // to serialize access to the display information.
538fc9822f3b20f6547c3398c55e8b70c4f3940db9Daniel Nicoara  composer_view_->ForceDisplaysRefresh();
54aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara  return binder::Status::ok();
55aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara}
56aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara
5715561b082ff4da3121be20d55b05a074ddd15a5cPat Plunkettbinder::Status VrComposer::clearObserver() {
5815561b082ff4da3121be20d55b05a074ddd15a5cPat Plunkett  std::lock_guard<std::mutex> guard(mutex_);
5915561b082ff4da3121be20d55b05a074ddd15a5cPat Plunkett  callback_ = nullptr;
6015561b082ff4da3121be20d55b05a074ddd15a5cPat Plunkett  return binder::Status::ok();
6115561b082ff4da3121be20d55b05a074ddd15a5cPat Plunkett}
6215561b082ff4da3121be20d55b05a074ddd15a5cPat Plunkett
63aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoarabase::unique_fd VrComposer::OnNewFrame(const ComposerView::Frame& frame) {
64aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara  std::lock_guard<std::mutex> guard(mutex_);
65aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara
66aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara  if (!callback_.get())
67aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara    return base::unique_fd();
68aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara
69aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara  ParcelableComposerFrame parcelable_frame(frame);
70aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara  ParcelableUniqueFd fence;
71aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara  binder::Status ret = callback_->onNewFrame(parcelable_frame, &fence);
72aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara  if (!ret.isOk())
73aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara    ALOGE("Failed to send new frame: %s", ret.toString8().string());
74aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara
75aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara  return fence.fence();
76aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara}
77aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara
78aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoaravoid VrComposer::binderDied(const wp<IBinder>& /* who */) {
79aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara  std::lock_guard<std::mutex> guard(mutex_);
80aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara
81aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara  callback_ = nullptr;
82aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara}
83aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara
84aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara}  // namespace dvr
85aba4d01add2e961f8b24a6281f3c616f916eb92fDaniel Nicoara}  // namespace android
86