Implement an API for vrwm to query if the current vr app is active
The API returns if the client_order 0 layer is visible or not. This
aids in 2D app detection
Bug: None
Test: Manual with permissionsgen & calculator
Change-Id: Id988e61a9f93885e93c28ed83ffaffd84f3bdf15
diff --git a/libs/vr/libdisplay/display_client.cpp b/libs/vr/libdisplay/display_client.cpp
index 50d95f7..9952e59 100644
--- a/libs/vr/libdisplay/display_client.cpp
+++ b/libs/vr/libdisplay/display_client.cpp
@@ -265,6 +265,12 @@
return BufferConsumer::Import(std::move(status));
}
+bool DisplayClient::IsVrAppRunning() {
+ auto status = InvokeRemoteMethod<DisplayRPC::IsVrAppRunning>();
+ if (!status)
+ return 0;
+ return static_cast<bool>(status.get());
+}
} // namespace dvr
} // namespace android
diff --git a/libs/vr/libdisplay/include/private/dvr/display_client.h b/libs/vr/libdisplay/include/private/dvr/display_client.h
index f579a8c..378f67c 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_client.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_client.h
@@ -110,6 +110,9 @@
std::unique_ptr<BufferConsumer> GetPoseBuffer();
+ // Temporary query for current VR status. Will be removed later.
+ bool IsVrAppRunning();
+
private:
friend BASE;
diff --git a/libs/vr/libdisplay/include/private/dvr/display_rpc.h b/libs/vr/libdisplay/include/private/dvr/display_rpc.h
index 7a2986a..ac08650 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_rpc.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_rpc.h
@@ -219,6 +219,7 @@
kOpVideoMeshSurfaceCreateProducerQueue,
kOpSetViewerParams,
kOpGetPoseBuffer,
+ kOpIsVrAppRunning,
};
// Aliases.
@@ -248,6 +249,7 @@
void(const ViewerParams& viewer_params));
PDX_REMOTE_METHOD(GetPoseBuffer, kOpGetPoseBuffer,
LocalChannelHandle(Void));
+ PDX_REMOTE_METHOD(IsVrAppRunning, kOpIsVrAppRunning, int(Void));
};
struct DisplayManagerRPC {
diff --git a/libs/vr/libvrflinger/display_service.cpp b/libs/vr/libvrflinger/display_service.cpp
index da7281b..c079187 100644
--- a/libs/vr/libvrflinger/display_service.cpp
+++ b/libs/vr/libvrflinger/display_service.cpp
@@ -94,6 +94,11 @@
*this, &DisplayService::OnGetPoseBuffer, message);
return 0;
+ case DisplayRPC::IsVrAppRunning::Opcode:
+ DispatchRemoteMethod<DisplayRPC::IsVrAppRunning>(
+ *this, &DisplayService::IsVrAppRunning, message);
+ return 0;
+
// Direct the surface specific messages to the surface instance.
case DisplayRPC::CreateBufferQueue::Opcode:
case DisplayRPC::SetAttributes::Opcode:
@@ -355,5 +360,15 @@
update_notifier_();
}
+int DisplayService::IsVrAppRunning(pdx::Message& message) {
+ bool visible = true;
+ ForEachDisplaySurface([&visible](const std::shared_ptr<DisplaySurface>& surface) {
+ if (surface->client_z_order() == 0 && !surface->IsVisible())
+ visible = false;
+ });
+
+ REPLY_SUCCESS_RETURN(message, visible, 0);
+}
+
} // namespace dvr
} // namespace android
diff --git a/libs/vr/libvrflinger/display_service.h b/libs/vr/libvrflinger/display_service.h
index 2a71b4a..8e96172 100644
--- a/libs/vr/libvrflinger/display_service.h
+++ b/libs/vr/libvrflinger/display_service.h
@@ -87,6 +87,9 @@
const ViewerParams& view_params);
pdx::LocalChannelHandle OnGetPoseBuffer(pdx::Message& message);
+ // Temporary query for current VR status. Will be removed later.
+ int IsVrAppRunning(pdx::Message& message);
+
// Called by DisplaySurface to signal that a surface property has changed and
// the display manager should be notified.
void NotifyDisplayConfigurationUpdate();
diff --git a/services/vr/vr_window_manager/application.cpp b/services/vr/vr_window_manager/application.cpp
index 3dfd9f1..c5c040f 100644
--- a/services/vr/vr_window_manager/application.cpp
+++ b/services/vr/vr_window_manager/application.cpp
@@ -112,6 +112,7 @@
void Application::DeallocateResources() {
if (graphics_context_)
dvrGraphicsContextDestroy(graphics_context_);
+ graphics_context_ = nullptr;
if (pose_client_)
dvrPoseDestroy(pose_client_);
diff --git a/services/vr/vr_window_manager/display_view.cpp b/services/vr/vr_window_manager/display_view.cpp
index 8a1c84d..e88e7d0 100644
--- a/services/vr/vr_window_manager/display_view.cpp
+++ b/services/vr/vr_window_manager/display_view.cpp
@@ -9,6 +9,7 @@
constexpr float kLayerScaleFactor = 3.0f;
constexpr unsigned int kMaximumPendingFrames = 8;
+constexpr uint32_t kSystemId = 1000;
// clang-format off
const GLfloat kVertices[] = {
@@ -98,12 +99,9 @@
// Determine if ths frame should be shown or hidden.
ViewMode CalculateVisibilityFromLayerConfig(const HwcCallback::Frame& frame,
- uint32_t *appid) {
+ uint32_t* appid) {
auto& layers = frame.layers();
- // TODO(achaulk): Figure out how to identify the current VR app for 2D app
- // detection.
-
size_t index;
// Skip all layers that we don't know about.
for (index = 0; index < layers.size(); index++) {
@@ -119,7 +117,7 @@
return ViewMode::Hidden;
}
- if(layers[index].appid != *appid) {
+ if (layers[index].appid != *appid) {
*appid = layers[index].appid;
return ViewMode::App;
}
@@ -202,7 +200,8 @@
}
base::unique_fd DisplayView::OnFrame(std::unique_ptr<HwcCallback::Frame> frame,
- bool debug_mode, bool* showing) {
+ bool debug_mode, bool is_vr_active,
+ bool* showing) {
uint32_t app = current_vr_app_;
ViewMode visibility = CalculateVisibilityFromLayerConfig(*frame.get(), &app);
@@ -214,7 +213,7 @@
} else if (visibility == ViewMode::App) {
// This is either a VR app switch or a 2D app launching.
// If we can have VR apps, update if it's 0.
- if (!always_2d_ && (current_vr_app_ == 0 || !use_2dmode_)) {
+ if (!always_2d_ && is_vr_active && !use_2dmode_ && app != kSystemId) {
visibility = ViewMode::Hidden;
current_vr_app_ = app;
}
diff --git a/services/vr/vr_window_manager/display_view.h b/services/vr/vr_window_manager/display_view.h
index 9483e8b..0d1355e 100644
--- a/services/vr/vr_window_manager/display_view.h
+++ b/services/vr/vr_window_manager/display_view.h
@@ -23,7 +23,7 @@
// Calls to these 3 functions must be synchronized.
base::unique_fd OnFrame(std::unique_ptr<HwcCallback::Frame> frame,
- bool debug_mode, bool* showing);
+ bool debug_mode, bool is_vr_active, bool* showing);
void AdvanceFrame();
void UpdateReleaseFence();
diff --git a/services/vr/vr_window_manager/shell_view.cpp b/services/vr/vr_window_manager/shell_view.cpp
index e17b2ae..67ef5d4 100644
--- a/services/vr/vr_window_manager/shell_view.cpp
+++ b/services/vr/vr_window_manager/shell_view.cpp
@@ -4,6 +4,7 @@
#include <GLES3/gl3.h>
#include <android/input.h>
#include <binder/IServiceManager.h>
+#include <dvr/graphics.h>
#include <hardware/hwcomposer2.h>
#include <inttypes.h>
#include <log/log.h>
@@ -125,6 +126,10 @@
if (!surface_flinger_view_->Initialize(this))
return 1;
+ // This is a temporary fix for now. These APIs will be changed when everything
+ // is moved into vrcore.
+ display_client_ = DisplayClient::Create();
+
return 0;
}
@@ -278,7 +283,11 @@
bool showing = false;
- base::unique_fd fd(display->OnFrame(std::move(frame), debug_mode_, &showing));
+ // TODO(achaulk): change when moved into vrcore.
+ bool vr_running = display_client_->IsVrAppRunning();
+
+ base::unique_fd fd(
+ display->OnFrame(std::move(frame), debug_mode_, vr_running, &showing));
if (showing)
QueueTask(MainThreadTask::Show);
diff --git a/services/vr/vr_window_manager/shell_view.h b/services/vr/vr_window_manager/shell_view.h
index 6887e7e..d265866 100644
--- a/services/vr/vr_window_manager/shell_view.h
+++ b/services/vr/vr_window_manager/shell_view.h
@@ -2,6 +2,7 @@
#define VR_WINDOW_MANAGER_SHELL_VIEW_H_
#include <dvr/virtual_touchpad_client.h>
+#include <private/dvr/display_client.h>
#include <private/dvr/graphics/mesh.h>
#include <private/dvr/graphics/shader_program.h>
@@ -66,6 +67,8 @@
std::unique_ptr<SurfaceFlingerView> surface_flinger_view_;
std::unique_ptr<Reticle> reticle_;
+ std::unique_ptr<DisplayClient> display_client_;
+
struct DvrVirtualTouchpadDeleter {
void operator()(DvrVirtualTouchpad* p) {
dvrVirtualTouchpadDetach(p);