Home | History | Annotate | Download | only in libvrflinger
      1 #include <dvr/vr_flinger.h>
      2 
      3 #include <errno.h>
      4 #include <fcntl.h>
      5 #include <poll.h>
      6 #include <signal.h>
      7 #include <string.h>
      8 #include <time.h>
      9 #include <unistd.h>
     10 #include <memory>
     11 
     12 #include <binder/IServiceManager.h>
     13 #include <binder/ProcessState.h>
     14 #include <cutils/properties.h>
     15 #include <cutils/sched_policy.h>
     16 #include <log/log.h>
     17 #include <private/dvr/display_client.h>
     18 #include <sys/prctl.h>
     19 #include <sys/resource.h>
     20 
     21 #include <functional>
     22 
     23 #include "DisplayHardware/ComposerHal.h"
     24 #include "display_manager_service.h"
     25 #include "display_service.h"
     26 #include "vsync_service.h"
     27 
     28 namespace android {
     29 namespace dvr {
     30 
     31 std::unique_ptr<VrFlinger> VrFlinger::Create(
     32     Hwc2::Composer* hidl, hwc2_display_t primary_display_id,
     33     RequestDisplayCallback request_display_callback) {
     34   std::unique_ptr<VrFlinger> vr_flinger(new VrFlinger);
     35   if (vr_flinger->Init(hidl, primary_display_id, request_display_callback))
     36     return vr_flinger;
     37   else
     38     return nullptr;
     39 }
     40 
     41 VrFlinger::VrFlinger() {}
     42 
     43 VrFlinger::~VrFlinger() {
     44   if (persistent_vr_state_callback_.get()) {
     45     sp<IVrManager> vr_manager = interface_cast<IVrManager>(
     46         defaultServiceManager()->checkService(String16("vrmanager")));
     47     if (vr_manager.get()) {
     48       vr_manager->unregisterPersistentVrStateListener(
     49           persistent_vr_state_callback_);
     50     }
     51   }
     52 
     53   if (dispatcher_)
     54     dispatcher_->SetCanceled(true);
     55   if (dispatcher_thread_.joinable())
     56     dispatcher_thread_.join();
     57 }
     58 
     59 bool VrFlinger::Init(Hwc2::Composer* hidl,
     60                      hwc2_display_t primary_display_id,
     61                      RequestDisplayCallback request_display_callback) {
     62   if (!hidl || !request_display_callback)
     63     return false;
     64 
     65   std::shared_ptr<android::pdx::Service> service;
     66 
     67   ALOGI("Starting up VrFlinger...");
     68 
     69   // We need to be able to create endpoints with full perms.
     70   umask(0000);
     71 
     72   android::ProcessState::self()->startThreadPool();
     73 
     74   request_display_callback_ = request_display_callback;
     75 
     76   dispatcher_ = android::pdx::ServiceDispatcher::Create();
     77   CHECK_ERROR(!dispatcher_, error, "Failed to create service dispatcher.");
     78 
     79   display_service_ = android::dvr::DisplayService::Create(
     80       hidl, primary_display_id, request_display_callback);
     81   CHECK_ERROR(!display_service_, error, "Failed to create display service.");
     82   dispatcher_->AddService(display_service_);
     83 
     84   service = android::dvr::DisplayManagerService::Create(display_service_);
     85   CHECK_ERROR(!service, error, "Failed to create display manager service.");
     86   dispatcher_->AddService(service);
     87 
     88   service = android::dvr::VSyncService::Create();
     89   CHECK_ERROR(!service, error, "Failed to create vsync service.");
     90   dispatcher_->AddService(service);
     91 
     92   display_service_->SetVSyncCallback(
     93       std::bind(&android::dvr::VSyncService::VSyncEvent,
     94                 std::static_pointer_cast<android::dvr::VSyncService>(service),
     95                 std::placeholders::_1, std::placeholders::_2,
     96                 std::placeholders::_3));
     97 
     98   dispatcher_thread_ = std::thread([this]() {
     99     prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("VrDispatch"), 0, 0, 0);
    100     ALOGI("Entering message loop.");
    101 
    102     setpriority(PRIO_PROCESS, 0, android::PRIORITY_URGENT_DISPLAY);
    103     set_sched_policy(0, SP_FOREGROUND);
    104 
    105     int ret = dispatcher_->EnterDispatchLoop();
    106     if (ret < 0) {
    107       ALOGE("Dispatch loop exited because: %s\n", strerror(-ret));
    108     }
    109   });
    110 
    111   return true;
    112 
    113 error:
    114   return false;
    115 }
    116 
    117 void VrFlinger::OnBootFinished() {
    118   display_service_->OnBootFinished();
    119   sp<IVrManager> vr_manager = interface_cast<IVrManager>(
    120       defaultServiceManager()->checkService(String16("vrmanager")));
    121   if (vr_manager.get()) {
    122     persistent_vr_state_callback_ =
    123         new PersistentVrStateCallback(request_display_callback_);
    124     vr_manager->registerPersistentVrStateListener(
    125         persistent_vr_state_callback_);
    126   } else {
    127     ALOGE("Unable to register vr flinger for persistent vr mode changes");
    128   }
    129 }
    130 
    131 void VrFlinger::GrantDisplayOwnership() {
    132   display_service_->GrantDisplayOwnership();
    133 }
    134 
    135 void VrFlinger::SeizeDisplayOwnership() {
    136   display_service_->SeizeDisplayOwnership();
    137 }
    138 
    139 std::string VrFlinger::Dump() {
    140   // TODO(karthikrs): Add more state information here.
    141   return display_service_->DumpState(0/*unused*/);
    142 }
    143 
    144 void VrFlinger::PersistentVrStateCallback::onPersistentVrStateChanged(
    145     bool enabled) {
    146   ALOGV("Notified persistent vr mode is %s", enabled ? "on" : "off");
    147   // TODO(eieio): Determine the correct signal to request display control.
    148   // Persistent VR mode is not enough.
    149   // request_display_callback_(enabled);
    150 }
    151 }  // namespace dvr
    152 }  // namespace android
    153