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 28namespace android { 29namespace dvr { 30 31std::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 41VrFlinger::VrFlinger() {} 42 43VrFlinger::~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 59bool 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 113error: 114 return false; 115} 116 117void 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 131void VrFlinger::GrantDisplayOwnership() { 132 display_service_->GrantDisplayOwnership(); 133} 134 135void VrFlinger::SeizeDisplayOwnership() { 136 display_service_->SeizeDisplayOwnership(); 137} 138 139std::string VrFlinger::Dump() { 140 // TODO(karthikrs): Add more state information here. 141 return display_service_->DumpState(0/*unused*/); 142} 143 144void 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