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