Default implementation for Automotive Display Service
Bug: 140395359
Test: m -j; adb shell lshal
Change-Id: I652873ebe4258d1bfc07570ac5ea844615bebc46
diff --git a/services/automotive/display/Android.bp b/services/automotive/display/Android.bp
new file mode 100644
index 0000000..5a5dc89
--- /dev/null
+++ b/services/automotive/display/Android.bp
@@ -0,0 +1,39 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+cc_binary {
+ name: "android.frameworks.automotive.display@1.0-service",
+ defaults: ["hidl_defaults"],
+ srcs: [
+ "main_automotivedisplay.cpp",
+ "CarWindowService.cpp",
+ ],
+ init_rc: ["android.frameworks.automotive.display@1.0-service.rc"],
+
+ shared_libs: [
+ "android.frameworks.automotive.display@1.0",
+ "android.hardware.graphics.bufferqueue@2.0",
+ "libgui",
+ "libhidlbase",
+ "liblog",
+ "libui",
+ "libutils",
+ ],
+
+ local_include_dirs: [
+ "include",
+ ],
+}
diff --git a/services/automotive/display/CarWindowService.cpp b/services/automotive/display/CarWindowService.cpp
new file mode 100644
index 0000000..e95c9e1
--- /dev/null
+++ b/services/automotive/display/CarWindowService.cpp
@@ -0,0 +1,121 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#include <ui/DisplayInfo.h>
+#include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
+
+#include "CarWindowService.h"
+
+namespace android {
+namespace frameworks {
+namespace automotive {
+namespace display {
+namespace V1_0 {
+namespace implementation {
+
+Return<sp<IGraphicBufferProducer>>
+ CarWindowService::getIGraphicBufferProducer() {
+ if (mSurface == nullptr) {
+ status_t err;
+ mSurfaceComposerClient = new SurfaceComposerClient();
+
+ err = mSurfaceComposerClient->initCheck();
+ if (err != NO_ERROR) {
+ ALOGE("SurfaceComposerClient::initCheck error: %#x", err);
+ mSurfaceComposerClient = nullptr;
+ return nullptr;
+ }
+
+ // Get main display parameters.
+ sp<IBinder> mainDpy = SurfaceComposerClient::getInternalDisplayToken();
+ if (mainDpy == nullptr) {
+ ALOGE("Failed to get internal display ");
+ return nullptr;
+ }
+ DisplayInfo mainDpyInfo;
+ err = SurfaceComposerClient::getDisplayInfo(mainDpy, &mainDpyInfo);
+ if (err != NO_ERROR) {
+ ALOGE("Failed to get display characteristics");
+ return nullptr;
+ }
+ unsigned int mWidth, mHeight;
+ if (mainDpyInfo.orientation != ui::ROTATION_0 &&
+ mainDpyInfo.orientation != ui::ROTATION_180) {
+ // rotated
+ mWidth = mainDpyInfo.h;
+ mHeight = mainDpyInfo.w;
+ } else {
+ mWidth = mainDpyInfo.w;
+ mHeight = mainDpyInfo.h;
+ }
+
+ mSurfaceControl = mSurfaceComposerClient->createSurface(
+ String8("Automotive Display"), mWidth, mHeight,
+ PIXEL_FORMAT_RGBX_8888, ISurfaceComposerClient::eOpaque);
+ if (mSurfaceControl == nullptr || !mSurfaceControl->isValid()) {
+ ALOGE("Failed to create SurfaceControl");
+ mSurfaceComposerClient = nullptr;
+ mSurfaceControl = nullptr;
+ return nullptr;
+ }
+
+ // SurfaceControl::getSurface is guaranteed to be not null.
+ mSurface = mSurfaceControl->getSurface();
+ }
+
+ return new ::android::hardware::graphics::bufferqueue::V2_0::utils::
+ B2HGraphicBufferProducer(
+ mSurface->getIGraphicBufferProducer());
+}
+
+Return<bool> CarWindowService::showWindow() {
+ status_t status = NO_ERROR;
+
+ if (mSurfaceControl != nullptr) {
+ status = SurfaceComposerClient::Transaction{}
+ .setLayer(
+ mSurfaceControl, 0x7FFFFFFF) // always on top
+ .show(mSurfaceControl)
+ .apply();
+ } else {
+ ALOGE("showWindow: Failed to get a valid SurfaceControl!");
+ return false;
+ }
+
+ return status == NO_ERROR;
+}
+
+Return<bool> CarWindowService::hideWindow() {
+ status_t status = NO_ERROR;
+
+ if (mSurfaceControl != nullptr) {
+ status = SurfaceComposerClient::Transaction{}
+ .hide(mSurfaceControl)
+ .apply();
+ } else {
+ ALOGE("hideWindow: Failed to get a valid SurfaceControl!");
+ return false;
+ }
+
+ return status == NO_ERROR;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace display
+} // namespace automotive
+} // namespace frameworks
+} // namespace android
+
diff --git a/services/automotive/display/android.frameworks.automotive.display@1.0-service.rc b/services/automotive/display/android.frameworks.automotive.display@1.0-service.rc
new file mode 100644
index 0000000..ffb7b5e
--- /dev/null
+++ b/services/automotive/display/android.frameworks.automotive.display@1.0-service.rc
@@ -0,0 +1,5 @@
+service automotive_display /system/bin/android.frameworks.automotive.display@1.0-service
+ class hal
+ user graphics
+ group automotive_evs
+ disabled # will not automatically start with its class; must be explicitly started.
diff --git a/services/automotive/display/include/CarWindowService.h b/services/automotive/display/include/CarWindowService.h
new file mode 100644
index 0000000..3290cc7
--- /dev/null
+++ b/services/automotive/display/include/CarWindowService.h
@@ -0,0 +1,52 @@
+//
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#pragma once
+
+#include <android/frameworks/automotive/display/1.0/ICarWindowService.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
+
+namespace android {
+namespace frameworks {
+namespace automotive {
+namespace display {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::Return;
+using ::android::sp;
+using ::android::hardware::graphics::bufferqueue::V2_0::IGraphicBufferProducer;
+
+class CarWindowService : public ICarWindowService {
+public:
+ Return<sp<IGraphicBufferProducer>> getIGraphicBufferProducer() override;
+ Return<bool> showWindow() override;
+ Return<bool> hideWindow() override;
+
+private:
+ sp<android::Surface> mSurface;
+ sp<android::SurfaceComposerClient> mSurfaceComposerClient;
+ sp<android::SurfaceControl> mSurfaceControl;
+};
+} // namespace implementation
+} // namespace V1_0
+} // namespace display
+} // namespace automotive
+} // namespace frameworks
+} // namespace android
+
diff --git a/services/automotive/display/main_automotivedisplay.cpp b/services/automotive/display/main_automotivedisplay.cpp
new file mode 100644
index 0000000..69f0a13
--- /dev/null
+++ b/services/automotive/display/main_automotivedisplay.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "AutomotiveDisplayService"
+
+#include <unistd.h>
+
+#include <hidl/HidlTransportSupport.h>
+#include <log/log.h>
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+
+#include "CarWindowService.h"
+
+// libhidl:
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+
+// Generated HIDL files
+using android::frameworks::automotive::display::V1_0::ICarWindowService;
+
+// The namespace in which all our implementation code lives
+using namespace android::frameworks::automotive::display::V1_0::implementation;
+using namespace android;
+
+const static char kServiceName[] = "default";
+
+int main() {
+ ALOGI("Car Window Service is starting");
+
+ android::sp<ICarWindowService> service = new CarWindowService();
+
+ configureRpcThreadpool(1, true /* callerWillJoin */);
+
+ // Register our service -- if somebody is already registered by our name,
+ // they will be killed (their thread pool will throw an exception).
+ status_t status = service->registerAsService(kServiceName);
+ if (status == OK) {
+ ALOGD("%s is ready.", kServiceName);
+ joinRpcThreadpool();
+ } else {
+ ALOGE("Could not register service %s (%d).", kServiceName, status);
+ }
+
+ // In normal operation, we don't expect the thread pool to exit
+ ALOGE("Car Window Service is shutting down");
+
+ return 1;
+}
+