OSDN Git Service

Add libhwcservice.
authorKalyan Kondapally <kalyan.kondapally@intel.com>
Tue, 13 Jun 2017 02:20:04 +0000 (19:20 -0700)
committerKalyan Kondapally <kalyan.kondapally@intel.com>
Tue, 13 Jun 2017 02:42:08 +0000 (19:42 -0700)
This is imported from VPG HWC code base.

Jira: None.
Test: Build passes on Android.

Signed-off-by: Kalyan Kondapally <kalyan.kondapally@intel.com>
14 files changed:
Android.mk
os/android/libhwcservice/Android.mk [new file with mode: 0644]
os/android/libhwcservice/hwcserviceapi.cpp [new file with mode: 0644]
os/android/libhwcservice/hwcserviceapi.h [new file with mode: 0644]
os/android/libhwcservice/hwcservicehelper.h [new file with mode: 0644]
os/android/libhwcservice/icontrols.cpp [new file with mode: 0644]
os/android/libhwcservice/icontrols.h [new file with mode: 0644]
os/android/libhwcservice/idiagnostic.cpp [new file with mode: 0644]
os/android/libhwcservice/idiagnostic.h [new file with mode: 0644]
os/android/libhwcservice/idisplayoverscancontrol.h [new file with mode: 0644]
os/android/libhwcservice/idisplayscalingcontrol.h [new file with mode: 0644]
os/android/libhwcservice/iservice.cpp [new file with mode: 0644]
os/android/libhwcservice/iservice.h [new file with mode: 0644]
public/hwclayer.h

index f647a11..326af58 100644 (file)
@@ -119,6 +119,12 @@ LOCAL_MODULE_CLASS := SHARED_LIBRARIES
 LOCAL_MODULE_SUFFIX := $(TARGET_SHLIB_SUFFIX)
 include $(BUILD_SHARED_LIBRARY)
 
+# libhwcservice
+HWC_BUILD_DIRS := \
+$(LOCAL_PATH)/os/android/libhwcservice/Android.mk
+
+include $(HWC_BUILD_DIRS)
+
 #Include tests only if eng build
 ifneq (,$(filter eng,$(TARGET_BUILD_VARIANT)))
 # Commenting for now include when ld issue is resolved
diff --git a/os/android/libhwcservice/Android.mk b/os/android/libhwcservice/Android.mk
new file mode 100644 (file)
index 0000000..2043536
--- /dev/null
@@ -0,0 +1,29 @@
+# Copyright (c) 2017 Intel Corporation
+#
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES += icontrols.cpp                \
+                   idiagnostic.cpp              \
+                   iservice.cpp                 \
+                   hwcserviceapi.cpp
+
+LOCAL_MODULE := libhwcservice
+LOCAL_CFLAGS += -fvisibility=default
+LOCAL_SHARED_LIBRARIES := libutils libbinder liblog
+LOCAL_MULTILIB := both
+LOCAL_EXPORT_C_INCLUDE_DIRS += $(LOCAL_PATH)
+include $(BUILD_SHARED_LIBRARY)
diff --git a/os/android/libhwcservice/hwcserviceapi.cpp b/os/android/libhwcservice/hwcserviceapi.cpp
new file mode 100644 (file)
index 0000000..0cdc839
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// 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 "hwcserviceapi.h"
+
+#include "icontrols.h"
+#include "iservice.h"
+
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+using namespace std;
+using namespace android;
+
+using namespace hwcomposer;
+
+extern "C" {
+struct HwcsContext {
+  sp<IService> mHwcService;
+  sp<IControls> mControls;
+};
+
+HWCSHANDLE HwcService_Connect() {
+  ProcessState::self()
+      ->startThreadPool();  // Required for starting binder threads
+
+  HwcsContext context;
+  context.mHwcService = interface_cast<IService>(
+      defaultServiceManager()->getService(String16(IA_HWC_SERVICE_NAME)));
+  if (context.mHwcService == NULL) {
+    return NULL;
+  }
+
+  context.mControls = context.mHwcService->getControls();
+  if (context.mControls == NULL) {
+    return NULL;
+  }
+
+  return new HwcsContext(context);
+}
+
+void HwcService_Disconnect(HWCSHANDLE hwcs) {
+  if (hwcs != NULL) {
+    delete static_cast<HwcsContext*>(hwcs);
+  }
+}
+
+const char* HwcService_GetHwcVersion(HWCSHANDLE hwcs) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return NULL;
+  }
+
+  static String8 version = pContext->mHwcService->getHwcVersion();
+  if (version.length() == 0) {
+    return NULL;
+  }
+  return version;
+}
+
+status_t HwcService_Display_SetOverscan(HWCSHANDLE hwcs, uint32_t display,
+                                        int32_t xoverscan, int32_t yoverscan) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->displaySetOverscan(display, xoverscan, yoverscan);
+}
+
+status_t HwcService_Display_GetOverscan(HWCSHANDLE hwcs, uint32_t display,
+                                        int32_t* xoverscan,
+                                        int32_t* yoverscan) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->displayGetOverscan(display, xoverscan, yoverscan);
+}
+
+status_t HwcService_Display_SetScaling(HWCSHANDLE hwcs, uint32_t display,
+                                       EHwcsScalingMode eScalingMode) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->displaySetScaling(display, eScalingMode);
+}
+
+status_t HwcService_Display_GetScaling(HWCSHANDLE hwcs, uint32_t display,
+                                       EHwcsScalingMode* eScalingMode) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->displayGetScaling(display, eScalingMode);
+}
+
+status_t HwcService_Display_EnableBlank(HWCSHANDLE hwcs, uint32_t display,
+                                        EHwcsBool blank) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->displayEnableBlank(display, blank);
+}
+
+status_t HwcService_Display_RestoreDefaultColorParam(HWCSHANDLE hwcs,
+                                                     uint32_t display,
+                                                     EHwcsColorControl color) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->displayRestoreDefaultColorParam(display, color);
+}
+
+status_t HwcService_Display_GetColorParam(HWCSHANDLE hwcs, uint32_t display,
+                                          EHwcsColorControl color, float* value,
+                                          float* startvalue, float* endvalue) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->displayGetColorParam(display, color, value,
+                                                   startvalue, endvalue);
+}
+
+status_t HwcService_Display_SetColorParam(HWCSHANDLE hwcs, uint32_t display,
+                                          EHwcsColorControl color,
+                                          float value) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->displaySetColorParam(display, color, value);
+}
+
+status_t HwcService_DisplayMode_GetAvailableModes(
+    HWCSHANDLE hwcs, uint32_t display, unsigned modeCount,
+    HwcsDisplayModeInfo* pModeList) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  Vector<HwcsDisplayModeInfo> modes =
+      pContext->mControls->displayModeGetAvailableModes(display);
+  if (pModeList && (modeCount > 0)) {
+    size_t count = modes.size();
+    if (count > modeCount)
+      count = modeCount;
+    memcpy(pModeList, modes.array(), sizeof(HwcsDisplayModeInfo) * count);
+  }
+  return modes.size();
+}
+
+status_t HwcService_DisplayMode_GetMode(HWCSHANDLE hwcs, uint32_t display,
+                                        HwcsDisplayModeInfo* pMode) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->displayModeGetMode(display, pMode);
+}
+
+status_t HwcService_DisplayMode_SetMode(HWCSHANDLE hwcs, uint32_t display,
+                                        const HwcsDisplayModeInfo* pMode) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->displayModeSetMode(display, pMode);
+}
+
+status_t HwcService_Video_EnableEncryptedSession(HWCSHANDLE hwcs,
+                                                 uint32_t sessionID,
+                                                 uint32_t instanceID) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->videoEnableEncryptedSession(sessionID,
+                                                          instanceID);
+}
+
+status_t HwcService_Video_DisableEncryptedSession(HWCSHANDLE hwcs,
+                                                  uint32_t sessionID) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->videoDisableEncryptedSession(sessionID);
+}
+
+status_t HwcService_Video_DisableAllEncryptedSessions(HWCSHANDLE hwcs) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->videoDisableAllEncryptedSessions();
+}
+
+EHwcsBool HwcService_Video_IsEncryptedSessionEnabled(HWCSHANDLE hwcs,
+                                                     uint32_t sessionID,
+                                                     uint32_t instanceID) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return HWCS_FALSE;
+  }
+  return pContext->mControls->videoIsEncryptedSessionEnabled(sessionID,
+                                                             instanceID)
+             ? HWCS_TRUE
+             : HWCS_FALSE;
+}
+
+status_t HwcService_Video_SetOptimizationMode(HWCSHANDLE hwcs,
+                                              EHwcsOptimizationMode mode) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->videoSetOptimizationMode(mode);
+}
+
+status_t HwcService_MDS_UpdateVideoState(HWCSHANDLE hwcs,
+                                         int64_t videoSessionID,
+                                         EHwcsBool isPrepared) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->mdsUpdateVideoState(videoSessionID, isPrepared);
+}
+
+status_t HwcService_MDS_UpdateVideoFPS(HWCSHANDLE hwcs, int64_t videoSessionID,
+                                       int32_t fps) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->mdsUpdateVideoFPS(videoSessionID, fps);
+}
+
+status_t HwcService_MDS_UpdateInputState(HWCSHANDLE hwcs, EHwcsBool state) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->mdsUpdateInputState(state);
+}
+
+status_t HwcService_Widi_GetSingleDisplay(HWCSHANDLE hwcs, EHwcsBool* enable) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  if (!enable) {
+    return android::BAD_VALUE;
+  }
+  bool bEnabled = false;
+  status_t ret = pContext->mControls->widiGetSingleDisplay(&bEnabled);
+  *enable = bEnabled ? HWCS_TRUE : HWCS_FALSE;
+  return ret;
+}
+
+status_t HwcService_Widi_SetSingleDisplay(HWCSHANDLE hwcs, EHwcsBool enable) {
+  HwcsContext* pContext = static_cast<HwcsContext*>(hwcs);
+  if (!pContext) {
+    return -1;
+  }
+  return pContext->mControls->widiSetSingleDisplay(enable);
+}
+}
diff --git a/os/android/libhwcservice/hwcserviceapi.h b/os/android/libhwcservice/hwcserviceapi.h
new file mode 100644 (file)
index 0000000..6af64e5
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// 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.
+*/
+
+#ifndef OS_ANDROID_HWC_HWCSERVICEAPI_H_
+#define OS_ANDROID_HWC_HWCSERVICEAPI_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Header file version.  Please increment on any API additions.
+// NOTE: Additions ONLY! No API modifications allowed (to maintain
+// compatability).
+#define HWCS_VERSION 1
+
+typedef void *HWCSHANDLE;
+
+typedef enum _EHwcsBool {
+  HWCS_FALSE = 0,
+  HWCS_TRUE = 1,
+} EHwcsBool;
+
+typedef int status_t;
+
+HWCSHANDLE HwcService_Connect();
+void HwcService_Disconnect(HWCSHANDLE hwcs);
+
+const char *HwcService_GetHwcVersion(HWCSHANDLE hwcs);
+
+// DisplayControl
+
+// Should these be hard coded in the API?
+enum {
+  HWCS_MAX_OVERSCAN = 100,   // The limit of the control parameters are
+                             // +/-HWCS_MAX_OVERSCAN inclusive.
+  HWCS_OVERSCAN_RANGE = 15,  // HWCS_OVERSCAN_RANGE describes the % of the
+                             // display size a max control setting will adjust
+                             // by.
+};
+
+/// Set overscan in the range +/-MAX_OVERSCAN inclusive.
+// -ve : zoom/crop the image  (increase display overscan).
+// +ve : shrink the image (decrease display overscan).
+status_t HwcService_Display_SetOverscan(HWCSHANDLE hwcs, uint32_t display,
+                                        int32_t xoverscan, int32_t yoverscan);
+// Get last set overscan.
+// Returns INVALID_OPERATION if overscan has not been set and
+// xoverscan/yoverscan are untouched.
+status_t HwcService_Display_GetOverscan(HWCSHANDLE hwcs, uint32_t display,
+                                        int32_t *xoverscan, int32_t *yoverscan);
+
+typedef enum _EHwcsScalingMode {
+  HWCS_SCALE_CENTRE =
+      0,               // Present the content centred at 1:1 source resolution.
+  HWCS_SCALE_STRETCH,  // Do not preserve aspect ratio - scale to fill the
+                       // display without cropping.
+  HWCS_SCALE_FIT,      // Preserve aspect ratio - scale to closest edge (may be
+                       // letterboxed or pillarboxed).
+  HWCS_SCALE_FILL,     // Preserve aspect ratio - scale to fill the display (may
+                       // crop the content).
+  HWCS_SCALE_MAX_ENUM  // End of enum.
+} EHwcsScalingMode;
+
+/// Set scaling to one of EScalingMode.
+// Returns OK if succesful.
+status_t HwcService_Display_SetScaling(HWCSHANDLE hwcs, uint32_t display,
+                                       EHwcsScalingMode eScalingMode);
+
+// Get last set scaling.
+// Returns OK if succesful.
+// Returns INVALID_OPERATION if scaling has not been set and eScalingMode is
+// untouched.
+status_t HwcService_Display_GetScaling(HWCSHANDLE hwcs, uint32_t display,
+                                       EHwcsScalingMode *eScalingMode);
+
+// Enable blank, true---blank, false---unblank
+// Returns OK if succesful.
+status_t HwcService_Display_EnableBlank(HWCSHANDLE hwcs, uint32_t display,
+                                        EHwcsBool blank);
+
+typedef enum _EHwcsColorControl {
+  HWCS_COLOR_BRIGHTNESS,
+  HWCS_COLOR_CONTRAST,
+  HWCS_COLOR_GAMMA,
+  HWCS_COLOR_SATURATION,
+  HWCS_COLOR_HUE,
+} EHwcsColorControl;
+
+status_t HwcService_Display_RestoreDefaultColorParam(HWCSHANDLE hwcs,
+                                                     uint32_t display,
+                                                     EHwcsColorControl color);
+status_t HwcService_Display_GetColorParam(HWCSHANDLE hwcs, uint32_t display,
+                                          EHwcsColorControl color, float *value,
+                                          float *startvalue, float *endvalue);
+status_t HwcService_Display_SetColorParam(HWCSHANDLE hwcs, uint32_t display,
+                                          EHwcsColorControl color, float value);
+
+// DisplayModeControl
+
+typedef enum _EHwcsModeFlags {
+  HWCS_MODE_FLAG_NONE = 0,
+  HWCS_MODE_FLAG_PREFERRED = 1 << 0,
+  HWCS_MODE_FLAG_SECURE = 1 << 1,
+  HWCS_MODE_FLAG_INTERLACED = 1 << 2,
+  HWCS_MODE_FLAG_CURRENT = 1 << 4,
+} EHwcsModeFlags;
+
+/// Enumerations for common aspect ratios
+/// Any ratio can be supported, with the upper 16 bits containing one dimension,
+/// the lower 16 bits contains the lower dimension
+typedef enum _EHwcsModeAspectRatio {
+  HWCS_MODE_ASPECT_RATIO_ANY = 0x00000000,
+  HWCS_MODE_ASPECT_RATIO_4_3 = 0x00040003,
+  HWCS_MODE_ASPECT_RATIO_16_9 = 0x00100009,
+} EHwcsModeAspectRatio;
+
+typedef struct _HwcsDisplayModeInfo {
+  uint32_t width;
+  uint32_t height;
+  uint32_t refresh;
+  uint32_t flags;  // EHwcsModeFlags
+  uint32_t ratio;  // EHwcsModeAspectRatio
+} HwcsDisplayModeInfo;
+
+/// query all available modes
+// If non-NULL: fills pModeList with up to modeCount modes.
+// Returns the number of modes available.
+status_t HwcService_DisplayMode_GetAvailableModes(
+    HWCSHANDLE hwcs, uint32_t display, unsigned modeCount,
+    HwcsDisplayModeInfo *pModeList);
+
+/// get current mode
+status_t HwcService_DisplayMode_GetMode(HWCSHANDLE hwcs, uint32_t display,
+                                        HwcsDisplayModeInfo *pMode);
+
+/// set mode
+status_t HwcService_DisplayMode_SetMode(HWCSHANDLE hwcs, uint32_t display,
+                                        const HwcsDisplayModeInfo *pMode);
+
+// VideoControl
+
+// The control enables a the protected video subsystem to control when to
+// replace any
+// encrypted content with a default bitmap (usually black).
+
+// Enable the display of encrypted buffers with the specified sessionID and
+// instanceID.
+// This will take effect from the next composed frame.
+// Any previously enabled instanceID will be disabled (replaced by the default
+// image)
+status_t HwcService_Video_EnableEncryptedSession(HWCSHANDLE hwcs,
+                                                 uint32_t sessionID,
+                                                 uint32_t instanceID);
+
+// Disable specific encrypted session.
+// This call will trigger the HWC to remove any encrypted buffers with the
+// specified sessionID
+// from the screen and replace with a default image.
+// The function will block until the screen no longer contains any encrypted
+// data with this session.
+// This should be called by any subsystem that knows that a specific encrypted
+// video session is about to
+// become invalid.
+status_t HwcService_Video_DisableEncryptedSession(HWCSHANDLE hwcs,
+                                                  uint32_t sessionID);
+
+// Disable all protected sessions.
+// This call will trigger the HWC to remove any encrypted buffers from the
+// screen and replace
+// with a default image.
+// The function will block until the screen no longer contains any encrypted
+// data with any session.
+// This should be called by any subsystem that knows that all encrypted video
+// sessions are about to
+// become invalid.
+status_t HwcService_Video_DisableAllEncryptedSessions(HWCSHANDLE hwcs);
+
+// Return whether or not the specified session/instance is enabled.
+EHwcsBool HwcService_Video_IsEncryptedSessionEnabled(HWCSHANDLE hwcs,
+                                                     uint32_t sessionID,
+                                                     uint32_t instanceID);
+
+// Hint provided by the application about the global optimization mode for the
+// driver
+typedef enum _EHwcsOptimizationMode {
+  HWCS_OPTIMIZE_NORMAL,
+  HWCS_OPTIMIZE_VIDEO,
+  HWCS_OPTIMIZE_CAMERA,
+} EHwcsOptimizationMode;
+status_t HwcService_Video_SetOptimizationMode(HWCSHANDLE hwcs,
+                                              EHwcsOptimizationMode mode);
+
+// MDS
+status_t HwcService_MDS_UpdateVideoState(HWCSHANDLE hwcs,
+                                         int64_t videoSessionID,
+                                         EHwcsBool isPrepared);
+
+status_t HwcService_MDS_UpdateVideoFPS(HWCSHANDLE hwcs, int64_t videoSessionID,
+                                       int32_t fps);
+
+status_t HwcService_MDS_UpdateInputState(HWCSHANDLE hwcs, EHwcsBool state);
+
+// Widi
+status_t HwcService_Widi_GetSingleDisplay(HWCSHANDLE hwcs, EHwcsBool *enable);
+status_t HwcService_Widi_SetSingleDisplay(HWCSHANDLE hwcs, EHwcsBool enable);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // OS_ANDROID_HWC_HWCSERVICEAPI_H_
diff --git a/os/android/libhwcservice/hwcservicehelper.h b/os/android/libhwcservice/hwcservicehelper.h
new file mode 100644 (file)
index 0000000..7245451
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// 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.
+*/
+
+#ifndef OS_ANDROID_HWC_HWCSERVICEHELPER_H_
+#define OS_ANDROID_HWC_HWCSERVICEHELPER_H_
+
+// Inline c++ helpers to augment HwcServiceApi.h
+
+#include <HwcServiceApi.h>
+
+#if __ANDROID__
+#include <utils/RefBase.h>
+
+class HwcServiceConnection : public android::RefBase {
+ public:
+  HwcServiceConnection() {
+    mHwcs = HwcService_Connect();
+  }
+  ~HwcServiceConnection() {
+    HwcService_Disconnect(mHwcs);
+  }
+  operator HWCSHANDLE() {
+    return mHwcs;
+  }
+  HWCSHANDLE handle() {
+    return mHwcs;
+  }
+
+ private:
+  // Non-copyable.
+  HwcServiceConnection(HwcServiceConnection const &);
+  void operator=(HwcServiceConnection const &);
+
+  HWCSHANDLE mHwcs;
+};
+
+#endif  // __ANDROID__
+
+#endif  // OS_ANDROID_HWC_HWCSERVICEHELPER_H_
diff --git a/os/android/libhwcservice/icontrols.cpp b/os/android/libhwcservice/icontrols.cpp
new file mode 100644 (file)
index 0000000..88740c7
--- /dev/null
@@ -0,0 +1,632 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// 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 "icontrols.h"
+#include <utils/String8.h>
+#include <binder/IPCThreadState.h>
+
+// For AID_ROOT & AID_MEDIA - various vendor code and utils include this despite
+// the path.
+#include <private/android_filesystem_config.h>
+
+namespace hwcomposer {
+
+using namespace android;
+
+/**
+ */
+class BpControls : public BpInterface<IControls> {
+ public:
+  BpControls(const sp<IBinder> &impl) : BpInterface<IControls>(impl) {
+  }
+
+  enum {
+    // ==============================================
+    // Public APIs - try not to reorder these
+
+    TRANSACT_DISPLAY_SET_OVERSCAN = IBinder::FIRST_CALL_TRANSACTION,
+    TRANSACT_DISPLAY_GET_OVERSCAN,
+    TRANSACT_DISPLAY_SET_SCALING,
+    TRANSACT_DISPLAY_GET_SCALING,
+    TRANSACT_DISPLAY_ENABLE_BLANK,
+    TRANSACT_DISPLAY_RESTORE_DEFAULT_COLOR_PARAM,
+    TRANSACT_DISPLAY_GET_COLOR_PARAM,
+    TRANSACT_DISPLAY_SET_COLOR_PARAM,
+    TRANSACT_DISPLAYMODE_GET_AVAILABLE_MODES,
+    TRANSACT_DISPLAYMODE_GET_MODE,
+    TRANSACT_DISPLAYMODE_SET_MODE,
+    TRANSACT_VIDEO_ENABLE_ENCRYPTED_SESSION,
+    TRANSACT_VIDEO_DISABLE_ENCRYPTED_SESSION,
+    TRANSACT_VIDEO_DISABLE_ALL_ENCRYPTED_SESSIONS,
+    TRANSACT_VIDEO_IS_ENCRYPTED_SESSION_ENABLED,
+    TRANSACT_VIDEO_SET_OPTIMIZATION_MODE,
+    TRANSACT_MDS_UPDATE_VIDEO_STATE,
+    TRANSACT_MDS_UPDATE_VIDEO_FPS,
+    TRANSACT_MDS_UPDATE_INPUT_STATE,
+    TRANSACT_WIDI_GET_SINGLE_DISPLAY,
+    TRANSACT_WIDI_SET_SINGLE_DISPLAY,
+  };
+
+  virtual status_t displaySetOverscan(uint32_t display, int32_t xoverscan,
+                                      int32_t yoverscan) {
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(IControls::getInterfaceDescriptor());
+    data.writeInt32(display);
+    data.writeInt32(xoverscan);
+    data.writeInt32(yoverscan);
+    status_t ret =
+        remote()->transact(TRANSACT_DISPLAY_SET_OVERSCAN, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return ret;
+    }
+    return reply.readInt32();
+  }
+
+  virtual status_t displayGetOverscan(uint32_t display, int32_t *xoverscan,
+                                      int32_t *yoverscan) {
+    if (!xoverscan || !yoverscan) {
+      return android::BAD_VALUE;
+    }
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(IControls::getInterfaceDescriptor());
+    data.writeInt32(display);
+    status_t ret =
+        remote()->transact(TRANSACT_DISPLAY_GET_OVERSCAN, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return ret;
+    }
+    status_t res = reply.readInt32();
+    if (res != OK)
+      return res;
+    *xoverscan = reply.readInt32();
+    *yoverscan = reply.readInt32();
+    return OK;
+  }
+
+  virtual status_t displaySetScaling(uint32_t display,
+                                     EHwcsScalingMode eScalingMode) {
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(IControls::getInterfaceDescriptor());
+    data.writeInt32(display);
+    data.writeInt32((int32_t)eScalingMode);
+    status_t ret =
+        remote()->transact(TRANSACT_DISPLAY_SET_SCALING, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return ret;
+    }
+    return reply.readInt32();
+  }
+
+  virtual status_t displayGetScaling(uint32_t display,
+                                     EHwcsScalingMode *eScalingMode) {
+    if (!eScalingMode) {
+      return android::BAD_VALUE;
+    }
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(IControls::getInterfaceDescriptor());
+    data.writeInt32(display);
+    status_t ret =
+        remote()->transact(TRANSACT_DISPLAY_GET_SCALING, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return ret;
+    }
+    status_t res = reply.readInt32();
+    if (res != OK)
+      return res;
+    *eScalingMode = (EHwcsScalingMode)reply.readInt32();
+    return OK;
+  }
+
+  virtual status_t displayEnableBlank(uint32_t display, bool blank) {
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(IControls::getInterfaceDescriptor());
+    data.writeInt32(display);
+    data.writeInt32((int32_t)blank);
+    status_t ret =
+        remote()->transact(TRANSACT_DISPLAY_ENABLE_BLANK, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return ret;
+    }
+    return reply.readInt32();
+  }
+
+  virtual status_t displayRestoreDefaultColorParam(uint32_t display,
+                                                   EHwcsColorControl color) {
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(getInterfaceDescriptor());
+    data.writeInt32(display);
+    data.writeInt32(color);
+    status_t ret = remote()->transact(
+        TRANSACT_DISPLAY_RESTORE_DEFAULT_COLOR_PARAM, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return ret;
+    }
+    return reply.readInt32();
+  }
+
+  virtual status_t displayGetColorParam(uint32_t display,
+                                        EHwcsColorControl color, float *value,
+                                        float *startvalue, float *endvalue) {
+    if (!value || !startvalue || !endvalue) {
+      return android::BAD_VALUE;
+    }
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(getInterfaceDescriptor());
+    data.writeInt32(display);
+    data.writeInt32(color);
+    status_t ret =
+        remote()->transact(TRANSACT_DISPLAY_GET_COLOR_PARAM, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return ret;
+    }
+    *value = reply.readInt32();
+    *startvalue = reply.readInt32();
+    *endvalue = reply.readInt32();
+    return reply.readInt32();
+  }
+
+  virtual status_t displaySetColorParam(uint32_t display,
+                                        EHwcsColorControl color, float value) {
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(getInterfaceDescriptor());
+    data.writeInt32(display);
+    data.writeInt32(color);
+    data.writeInt32(value);
+    status_t ret =
+        remote()->transact(TRANSACT_DISPLAY_SET_COLOR_PARAM, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return ret;
+    }
+    return reply.readInt32();
+  }
+
+  virtual Vector<HwcsDisplayModeInfo> displayModeGetAvailableModes(
+      uint32_t display) {
+    Vector<HwcsDisplayModeInfo> vector;
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(getInterfaceDescriptor());
+    data.writeInt32(display);
+    status_t ret = remote()->transact(TRANSACT_DISPLAYMODE_GET_AVAILABLE_MODES,
+                                      data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return vector;
+    }
+    int32_t n = reply.readInt32();
+    vector.setCapacity(n);
+    while (n--) {
+      HwcsDisplayModeInfo info;
+      info.width = reply.readInt32();
+      info.height = reply.readInt32();
+      info.refresh = reply.readInt32();
+      info.flags = reply.readInt32();
+      info.ratio = reply.readInt32();
+      vector.add(info);
+    }
+    return vector;
+  }
+
+  virtual status_t displayModeGetMode(uint32_t display,
+                                      HwcsDisplayModeInfo *pMode) {
+    if (!pMode) {
+      return android::BAD_VALUE;
+    }
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(getInterfaceDescriptor());
+    data.writeInt32(display);
+    status_t ret =
+        remote()->transact(TRANSACT_DISPLAYMODE_GET_MODE, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return ret;
+    }
+    pMode->width = reply.readInt32();
+    pMode->height = reply.readInt32();
+    pMode->refresh = reply.readInt32();
+    pMode->flags = reply.readInt32();
+    pMode->ratio = reply.readInt32();
+    return reply.readInt32();
+  }
+
+  virtual status_t displayModeSetMode(uint32_t display,
+                                      const HwcsDisplayModeInfo *pMode) {
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(getInterfaceDescriptor());
+    data.writeInt32(display);
+    data.writeInt32(pMode->width);
+    data.writeInt32(pMode->height);
+    data.writeInt32(pMode->refresh);
+    data.writeInt32(pMode->flags);
+    data.writeInt32(pMode->ratio);
+    status_t ret =
+        remote()->transact(TRANSACT_DISPLAYMODE_SET_MODE, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return ret;
+    }
+    return reply.readInt32();
+  }
+
+  virtual status_t videoEnableEncryptedSession(uint32_t sessionID,
+                                               uint32_t instanceID) {
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(IControls::getInterfaceDescriptor());
+    data.writeInt32(sessionID);
+    data.writeInt32(instanceID);
+    status_t ret = remote()->transact(TRANSACT_VIDEO_ENABLE_ENCRYPTED_SESSION,
+                                      data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return ret;
+    }
+    return reply.readInt32();
+  }
+
+  virtual status_t videoDisableEncryptedSession(uint32_t sessionID) {
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(IControls::getInterfaceDescriptor());
+    data.writeInt32(sessionID);
+    status_t ret = remote()->transact(TRANSACT_VIDEO_DISABLE_ENCRYPTED_SESSION,
+                                      data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+    }
+    return reply.readInt32();
+  }
+
+  virtual status_t videoDisableAllEncryptedSessions() {
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(IControls::getInterfaceDescriptor());
+    status_t ret = remote()->transact(
+        TRANSACT_VIDEO_DISABLE_ALL_ENCRYPTED_SESSIONS, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+    }
+    return reply.readInt32();
+  }
+
+  virtual bool videoIsEncryptedSessionEnabled(uint32_t sessionID,
+                                              uint32_t instanceID) {
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(IControls::getInterfaceDescriptor());
+    data.writeInt32(sessionID);
+    data.writeInt32(instanceID);
+    status_t ret = remote()->transact(
+        TRANSACT_VIDEO_IS_ENCRYPTED_SESSION_ENABLED, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return false;
+    }
+    return reply.readInt32();
+  }
+
+  virtual status_t videoSetOptimizationMode(EHwcsOptimizationMode mode) {
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(IControls::getInterfaceDescriptor());
+    data.writeInt32(mode);
+    status_t ret =
+        remote()->transact(TRANSACT_VIDEO_SET_OPTIMIZATION_MODE, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return ret;
+    }
+    return reply.readInt32();
+  }
+
+  virtual status_t mdsUpdateVideoState(int64_t videoSessionID,
+                                       bool isPrepared) {
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(IControls::getInterfaceDescriptor());
+    data.writeInt64(videoSessionID);
+    data.writeInt32(isPrepared);
+    status_t ret =
+        remote()->transact(TRANSACT_MDS_UPDATE_VIDEO_STATE, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return ret;
+    }
+    return reply.readInt32();
+  }
+
+  virtual status_t mdsUpdateVideoFPS(int64_t videoSessionID, int32_t fps) {
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(IControls::getInterfaceDescriptor());
+    data.writeInt64(videoSessionID);
+    data.writeInt32(fps);
+    status_t ret =
+        remote()->transact(TRANSACT_MDS_UPDATE_VIDEO_FPS, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+    }
+    return reply.readInt32();
+  }
+
+  virtual status_t mdsUpdateInputState(bool state) {
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(IControls::getInterfaceDescriptor());
+    data.writeInt32(state);
+    status_t ret =
+        remote()->transact(TRANSACT_MDS_UPDATE_INPUT_STATE, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+    }
+    return reply.readInt32();
+  }
+
+  virtual status_t widiGetSingleDisplay(bool *pEnabled) {
+    if (!pEnabled) {
+      return android::BAD_VALUE;
+    }
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(getInterfaceDescriptor());
+    status_t ret =
+        remote()->transact(TRANSACT_WIDI_GET_SINGLE_DISPLAY, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return ret;
+    }
+    *pEnabled = reply.readInt32();
+    return reply.readInt32();
+  }
+
+  virtual status_t widiSetSingleDisplay(bool enable) {
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(IControls::getInterfaceDescriptor());
+    data.writeInt32(enable);
+    status_t ret =
+        remote()->transact(TRANSACT_WIDI_SET_SINGLE_DISPLAY, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+    }
+    return reply.readInt32();
+  }
+};
+
+IMPLEMENT_META_INTERFACE(Controls, "intel.ufo.hwc.controls");
+
+status_t BnControls::onTransact(uint32_t code, const Parcel &data,
+                                Parcel *reply, uint32_t flags) {
+  switch (code) {
+    case BpControls::TRANSACT_DISPLAY_SET_OVERSCAN: {
+      CHECK_INTERFACE(IControls, data, reply);
+      uint32_t display = data.readInt32();
+      int32_t xoverscan = data.readInt32();
+      int32_t yoverscan = data.readInt32();
+      status_t ret = this->displaySetOverscan(display, xoverscan, yoverscan);
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_DISPLAY_GET_OVERSCAN: {
+      CHECK_INTERFACE(IControls, data, reply);
+      uint32_t display = data.readInt32();
+      int32_t xoverscan;
+      int32_t yoverscan;
+      status_t ret = this->displayGetOverscan(display, &xoverscan, &yoverscan);
+      reply->writeInt32(ret);
+      reply->writeInt32(xoverscan);
+      reply->writeInt32(yoverscan);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_DISPLAY_SET_SCALING: {
+      CHECK_INTERFACE(IControls, data, reply);
+      uint32_t display = data.readInt32();
+      EHwcsScalingMode scaling = (EHwcsScalingMode)data.readInt32();
+      status_t ret = this->displaySetScaling(display, scaling);
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_DISPLAY_GET_SCALING: {
+      CHECK_INTERFACE(IControls, data, reply);
+      uint32_t display = data.readInt32();
+      EHwcsScalingMode scaling;
+      status_t ret = this->displayGetScaling(display, &scaling);
+      reply->writeInt32(ret);
+      reply->writeInt32((int32_t)scaling);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_DISPLAY_ENABLE_BLANK: {
+      CHECK_INTERFACE(IControls, data, reply);
+      uint32_t display = data.readInt32();
+      bool blank = (bool)data.readInt32();
+      status_t ret = this->displayEnableBlank(display, blank);
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_DISPLAY_RESTORE_DEFAULT_COLOR_PARAM: {
+      CHECK_INTERFACE(IControls, data, reply);
+      uint32_t display = data.readInt32();
+      EHwcsColorControl color = (EHwcsColorControl)data.readInt32();
+      status_t ret = this->displayRestoreDefaultColorParam(display, color);
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_DISPLAY_GET_COLOR_PARAM: {
+      CHECK_INTERFACE(IControls, data, reply);
+      uint32_t display = data.readInt32();
+      EHwcsColorControl color = (EHwcsColorControl)data.readInt32();
+      float value;
+      float startvalue;
+      float endvalue;
+      status_t ret = this->displayGetColorParam(display, color, &value,
+                                                &startvalue, &endvalue);
+      reply->writeFloat(value);
+      reply->writeFloat(startvalue);
+      reply->writeFloat(endvalue);
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_DISPLAY_SET_COLOR_PARAM: {
+      CHECK_INTERFACE(IControls, data, reply);
+      uint32_t display = data.readInt32();
+      EHwcsColorControl color = (EHwcsColorControl)data.readInt32();
+      float value = data.readFloat();
+      status_t ret = this->displaySetColorParam(display, color, value);
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_DISPLAYMODE_GET_AVAILABLE_MODES: {
+      CHECK_INTERFACE(IControls, data, reply);
+      uint32_t display = data.readInt32();
+
+      Vector<HwcsDisplayModeInfo> vector =
+          this->displayModeGetAvailableModes(display);
+      reply->writeInt32(vector.size());
+      for (uint32_t i = 0; i < vector.size(); i++) {
+        reply->writeInt32(vector[i].width);
+        reply->writeInt32(vector[i].height);
+        reply->writeInt32(vector[i].refresh);
+        reply->writeInt32(vector[i].flags);
+        reply->writeInt32(vector[i].ratio);
+      }
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_DISPLAYMODE_GET_MODE: {
+      CHECK_INTERFACE(IControls, data, reply);
+      uint32_t display = data.readInt32();
+      HwcsDisplayModeInfo info;
+      status_t ret = this->displayModeGetMode(display, &info);
+      reply->writeInt32(info.width);
+      reply->writeInt32(info.height);
+      reply->writeInt32(info.refresh);
+      reply->writeInt32(info.flags);
+      reply->writeInt32(info.ratio);
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_DISPLAYMODE_SET_MODE: {
+      CHECK_INTERFACE(IControls, data, reply);
+      uint32_t display = data.readInt32();
+      HwcsDisplayModeInfo info;
+      info.width = data.readInt32();
+      info.height = data.readInt32();
+      info.refresh = data.readInt32();
+      info.flags = data.readInt32();
+      info.ratio = data.readInt32();
+      status_t ret = this->displayModeSetMode(display, &info);
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_VIDEO_ENABLE_ENCRYPTED_SESSION: {
+      CHECK_INTERFACE(IControls, data, reply);
+      uint32_t sessionID = data.readInt32();
+      uint32_t instanceID = data.readInt32();
+      status_t ret = this->videoEnableEncryptedSession(sessionID, instanceID);
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_VIDEO_DISABLE_ENCRYPTED_SESSION: {
+      CHECK_INTERFACE(IControls, data, reply);
+      int32_t sessionID = data.readInt32();
+      status_t ret = this->videoDisableEncryptedSession(sessionID);
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_VIDEO_DISABLE_ALL_ENCRYPTED_SESSIONS: {
+      CHECK_INTERFACE(IControls, data, reply);
+      status_t ret = this->videoDisableAllEncryptedSessions();
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_VIDEO_IS_ENCRYPTED_SESSION_ENABLED: {
+      CHECK_INTERFACE(IControls, data, reply);
+      uint32_t sessionID = data.readInt32();
+      uint32_t instanceID = data.readInt32();
+      bool bEnabled =
+          this->videoIsEncryptedSessionEnabled(sessionID, instanceID);
+      reply->writeInt32(bEnabled);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_VIDEO_SET_OPTIMIZATION_MODE: {
+      CHECK_INTERFACE(IControls, data, reply);
+      EHwcsOptimizationMode mode = (EHwcsOptimizationMode)data.readInt32();
+      status_t ret = this->videoSetOptimizationMode(mode);
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_MDS_UPDATE_VIDEO_STATE: {
+      CHECK_INTERFACE(IControls, data, reply);
+      int64_t videoSessionID = data.readInt64();
+      bool isPrepared = data.readInt32();
+      status_t ret = this->mdsUpdateVideoState(videoSessionID, isPrepared);
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_MDS_UPDATE_VIDEO_FPS: {
+      CHECK_INTERFACE(IControls, data, reply);
+      int64_t videoSessionID = data.readInt64();
+      int32_t fps = data.readInt32();
+      status_t ret = this->mdsUpdateVideoFPS(videoSessionID, fps);
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_MDS_UPDATE_INPUT_STATE: {
+      CHECK_INTERFACE(IControls, data, reply);
+      bool state = data.readInt32();
+      status_t ret = this->mdsUpdateInputState(state);
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_WIDI_GET_SINGLE_DISPLAY: {
+      CHECK_INTERFACE(IControls, data, reply);
+      bool enable = false;
+      status_t ret = this->widiGetSingleDisplay(&enable);
+      reply->writeInt32(enable);
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+    case BpControls::TRANSACT_WIDI_SET_SINGLE_DISPLAY: {
+      CHECK_INTERFACE(IControls, data, reply);
+      bool enable = data.readInt32();
+      status_t ret = this->widiSetSingleDisplay(enable);
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+
+    default:
+      return BBinder::onTransact(code, data, reply, flags);
+  }
+}
+
+}  // namespace hwcomposer
diff --git a/os/android/libhwcservice/icontrols.h b/os/android/libhwcservice/icontrols.h
new file mode 100644 (file)
index 0000000..33d97ff
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// 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.
+*/
+
+#ifndef OS_ANDROID_HWC_ICONTROLS_H_
+#define OS_ANDROID_HWC_ICONTROLS_H_
+
+#include "hwcserviceapi.h"
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace hwcomposer {
+
+class IControls : public android::IInterface {
+ public:
+  DECLARE_META_INTERFACE(Controls);
+
+  virtual status_t displaySetOverscan(uint32_t display, int32_t xoverscan,
+                                      int32_t yoverscan) = 0;
+  virtual status_t displayGetOverscan(uint32_t display, int32_t *xoverscan,
+                                      int32_t *yoverscan) = 0;
+  virtual status_t displaySetScaling(uint32_t display,
+                                     EHwcsScalingMode eScalingMode) = 0;
+  virtual status_t displayGetScaling(uint32_t display,
+                                     EHwcsScalingMode *eScalingMode) = 0;
+  virtual status_t displayEnableBlank(uint32_t display, bool blank) = 0;
+  virtual status_t displayRestoreDefaultColorParam(uint32_t display,
+                                                   EHwcsColorControl color) = 0;
+  virtual status_t displayGetColorParam(uint32_t display,
+                                        EHwcsColorControl color, float *value,
+                                        float *startvalue, float *endvalue) = 0;
+  virtual status_t displaySetColorParam(uint32_t display,
+                                        EHwcsColorControl color,
+                                        float value) = 0;
+
+  virtual android::Vector<HwcsDisplayModeInfo> displayModeGetAvailableModes(
+      uint32_t display) = 0;
+  virtual status_t displayModeGetMode(uint32_t display,
+                                      HwcsDisplayModeInfo *pMode) = 0;
+  virtual status_t displayModeSetMode(uint32_t display,
+                                      const HwcsDisplayModeInfo *pMode) = 0;
+
+  virtual status_t videoEnableEncryptedSession(uint32_t sessionID,
+                                               uint32_t instanceID) = 0;
+  virtual status_t videoDisableEncryptedSession(uint32_t sessionID) = 0;
+  virtual status_t videoDisableAllEncryptedSessions() = 0;
+  virtual bool videoIsEncryptedSessionEnabled(uint32_t sessionID,
+                                              uint32_t instanceID) = 0;
+  virtual status_t videoSetOptimizationMode(EHwcsOptimizationMode mode) = 0;
+
+  virtual status_t mdsUpdateVideoState(int64_t videoSessionID,
+                                       bool isPrepared) = 0;
+  virtual status_t mdsUpdateVideoFPS(int64_t videoSessionID, int32_t fps) = 0;
+  virtual status_t mdsUpdateInputState(bool state) = 0;
+
+  virtual status_t widiGetSingleDisplay(bool *pEnabled) = 0;
+  virtual status_t widiSetSingleDisplay(bool enable) = 0;
+};
+
+class BnControls : public android::BnInterface<IControls> {
+ public:
+  virtual status_t onTransact(uint32_t, const android::Parcel &,
+                              android::Parcel *, uint32_t);
+};
+
+}  // namespace hwcomposer
+
+#endif  // OS_ANDROID_HWC_ICONTROLS_H_
diff --git a/os/android/libhwcservice/idiagnostic.cpp b/os/android/libhwcservice/idiagnostic.cpp
new file mode 100644 (file)
index 0000000..f822d92
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// 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 "idiagnostic.h"
+#include <utils/String8.h>
+#include <binder/Parcel.h>
+#include <binder/IInterface.h>
+
+namespace hwcomposer {
+
+using namespace android;
+
+class BpDiagnostic : public BpInterface<IDiagnostic> {
+ public:
+  BpDiagnostic(const sp<IBinder>& impl)
+      : BpInterface<IDiagnostic>(impl), mReply(0) {
+  }
+
+  enum {
+    TRANSACT_READ_LOG_PARCEL = IBinder::FIRST_CALL_TRANSACTION,
+    TRANSACT_ENABLE_DISPLAY,
+    TRANSACT_DISABLE_DISPLAY,
+    TRANSACT_MASK_LAYER,
+    TRANSACT_DUMP_FRAMES
+  };
+
+  virtual ~BpDiagnostic() {
+    if (mReply)
+      delete mReply;
+  }
+
+  status_t readLogParcel(Parcel* reply) {
+    Parcel data;
+    data.writeInterfaceToken(IDiagnostic::getInterfaceDescriptor());
+    status_t ret = remote()->transact(TRANSACT_READ_LOG_PARCEL, data, reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+    }
+    return ret;
+  }
+
+  void enableDisplay(uint32_t d) {
+    Parcel data, reply;
+    data.writeInterfaceToken(IDiagnostic::getInterfaceDescriptor());
+    data.writeInt32(d);
+    status_t ret = remote()->transact(TRANSACT_ENABLE_DISPLAY, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return;
+    }
+  }
+
+  void disableDisplay(uint32_t d, bool bBlank) {
+    Parcel data, reply;
+    data.writeInterfaceToken(IDiagnostic::getInterfaceDescriptor());
+    data.writeInt32(d);
+    data.writeInt32(bBlank);
+    status_t ret = remote()->transact(TRANSACT_DISABLE_DISPLAY, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return;
+    }
+  }
+
+  void maskLayer(uint32_t d, uint32_t layer, bool bHide) {
+    Parcel data, reply;
+    data.writeInterfaceToken(IDiagnostic::getInterfaceDescriptor());
+    data.writeInt32(d);
+    data.writeInt32(layer);
+    data.writeInt32(bHide);
+    status_t ret = remote()->transact(TRANSACT_MASK_LAYER, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return;
+    }
+  }
+
+  void dumpFrames(uint32_t d, int32_t frames, bool bSync) {
+    Parcel data, reply;
+    data.writeInterfaceToken(IDiagnostic::getInterfaceDescriptor());
+    data.writeInt32(d);
+    data.writeInt32(frames);
+    data.writeInt32(bSync);
+    status_t ret = remote()->transact(TRANSACT_DUMP_FRAMES, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+      return;
+    }
+  }
+
+ private:
+  Parcel* mReply;
+};
+
+IMPLEMENT_META_INTERFACE(Diagnostic, "ia.hwc.diagnostic");
+
+status_t BnDiagnostic::onTransact(uint32_t code, const Parcel& data,
+                                  Parcel* reply, uint32_t flags) {
+  switch (code) {
+    case BpDiagnostic::TRANSACT_READ_LOG_PARCEL: {
+      CHECK_INTERFACE(IDiagnostic, data, reply);
+      status_t err = readLogParcel(reply);
+      return err;
+    }
+
+    case BpDiagnostic::TRANSACT_ENABLE_DISPLAY: {
+      CHECK_INTERFACE(IDiagnostic, data, reply);
+      uint32_t d = data.readInt32();
+      enableDisplay(d);
+      return NO_ERROR;
+    }
+
+    case BpDiagnostic::TRANSACT_DISABLE_DISPLAY: {
+      CHECK_INTERFACE(IDiagnostic, data, reply);
+      uint32_t d = data.readInt32();
+      bool bBlank = data.readInt32();
+      disableDisplay(d, bBlank);
+      return NO_ERROR;
+    }
+
+    case BpDiagnostic::TRANSACT_MASK_LAYER: {
+      CHECK_INTERFACE(IDiagnostic, data, reply);
+      uint32_t d = data.readInt32();
+      uint32_t layer = data.readInt32();
+      bool bHide = data.readInt32();
+      maskLayer(d, layer, bHide);
+      return NO_ERROR;
+    }
+
+    case BpDiagnostic::TRANSACT_DUMP_FRAMES: {
+      CHECK_INTERFACE(IDiagnostic, data, reply);
+      uint32_t d = data.readInt32();
+      int32_t frames = data.readInt32();
+      bool bSync = data.readInt32();
+      dumpFrames(d, frames, bSync);
+      return NO_ERROR;
+    }
+
+    default:
+      return BBinder::onTransact(code, data, reply, flags);
+  }
+}
+
+}  // namespace hwcomposer
diff --git a/os/android/libhwcservice/idiagnostic.h b/os/android/libhwcservice/idiagnostic.h
new file mode 100644 (file)
index 0000000..45b120a
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// 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.
+*/
+
+#ifndef OS_ANDROID_HWC_IDIAGNOSTIC_H
+#define OS_ANDROID_HWC_IDIAGNOSTIC_H
+
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace hwcomposer {
+
+using namespace android;
+
+class IDiagnostic : public IInterface {
+ public:
+  DECLARE_META_INTERFACE(Diagnostic);
+
+  // This class is shared with the validation team. Take care when changing it
+  // that
+  // the validation tests understand how we have changed this.
+  enum {
+    eLogTruncated =
+        101,  // Status to indicate log entries have been overwritten
+  };
+
+  virtual status_t readLogParcel(android::Parcel* reply) = 0;
+
+  // Debug API
+  virtual void enableDisplay(uint32_t d) = 0;
+  virtual void disableDisplay(uint32_t d, bool bBlank) = 0;
+  virtual void maskLayer(uint32_t d, uint32_t layer, bool bHide) = 0;
+  virtual void dumpFrames(uint32_t d, int32_t frames, bool bSync) = 0;
+};
+
+class BnDiagnostic : public android::BnInterface<IDiagnostic> {
+ public:
+  BnDiagnostic() {
+  }
+
+  virtual ~BnDiagnostic() {
+  }
+
+  virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);
+};
+
+}  // hwcomposer
+
+#endif  // OS_ANDROID_HWC_IDIAGNOSTIC_H
diff --git a/os/android/libhwcservice/idisplayoverscancontrol.h b/os/android/libhwcservice/idisplayoverscancontrol.h
new file mode 100644 (file)
index 0000000..24442b7
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// 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.
+*/
+
+#ifndef OS_ANDROID_IDISPLAY_OVERSCAN_CONTROL_H_
+#define OS_ANDROID_IDISPLAY_OVERSCAN_CONTROL_H_
+
+#include "hwcservicehelper.h"
+#include <utils/RefBase.h>
+
+namespace hwcomposer {
+
+/**
+ * Allows control of HDMI overscan
+ */
+class IDisplayOverscanControl : public android::RefBase {
+ public:
+  IDisplayOverscanControl(uint32_t display) : mDisplay(display) {
+  }
+
+  enum {
+    MAX_OVERSCAN = HWCS_MAX_OVERSCAN,  // The limit of the control parameters
+                                       // are +/-MAX_OVERSCAN inclusive.
+    RANGE = HWCS_OVERSCAN_RANGE,  // RANGE describes the % of the display size a
+                                  // max control setting will adjust by.
+  };
+
+  /// Set overscan in the range +/-MAX_OVERSCAN inclusive.
+  // -ve : zoom/crop the image  (increase display overscan).
+  // +ve : shrink the image (decrease display overscan).
+  status_t setOverscan(int32_t xoverscan, int32_t yoverscan) {
+    return HwcService_Display_SetOverscan(mHwcConn, mDisplay, xoverscan,
+                                          yoverscan);
+  }
+
+  // Get last set overscan.
+  // Returns INVALID_OPERATION if overscan has not been set and
+  // xoverscan/yoverscan are untouched.
+  status_t getOverscan(int32_t *xoverscan, int32_t *yoverscan) {
+    return HwcService_Display_GetOverscan(mHwcConn, mDisplay, xoverscan,
+                                          yoverscan);
+  }
+
+ private:
+  HwcServiceConnection mHwcConn;
+  uint32_t mDisplay;
+};
+
+}  // namespace hwcomposer
+
+#endif  // OS_ANDROID_IDISPLAY_OVERSCAN_CONTROL_H_
diff --git a/os/android/libhwcservice/idisplayscalingcontrol.h b/os/android/libhwcservice/idisplayscalingcontrol.h
new file mode 100644 (file)
index 0000000..4d52e5e
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// 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.
+*/
+
+#ifndef OS_ANDROID_IDISPLAY_SCALING_CONTROL_H_
+#define OS_ANDROID_IDISPLAY_SCALING_CONTROL_H_
+
+#include "hwcservicehelper.h"
+#include <utils/RefBase.h>
+
+namespace hwcomposer {
+
+/**
+ * Allows control of HDMI scaling for content
+ * that does not match the native display resolution.
+ */
+class IDisplayScalingControl : public android::RefBase {
+ public:
+  IDisplayScalingControl(uint32_t display) : mDisplay(display) {
+  }
+
+  enum EScalingMode {
+    SCALE_CENTRE = HWCS_SCALE_CENTRE,    // Present the content centred at 1:1
+                                         // source resolution.
+    SCALE_STRETCH = HWCS_SCALE_STRETCH,  // Do not preserve aspect ratio - scale
+                                         // to fill the display without
+                                         // cropping.
+    SCALE_FIT = HWCS_SCALE_FIT,    // Preserve aspect ratio - scale to closest
+                                   // edge (may be letterboxed or pillarboxed).
+    SCALE_FILL = HWCS_SCALE_FILL,  // Preserve aspect ratio - scale to fill the
+                                   // display (may crop the content).
+    SCALE_MAX_ENUM = HWCS_SCALE_MAX_ENUM  // End of enum.
+  };
+
+  /// Set scaling to one of EScalingMode.
+  // Returns OK if succesful.
+  status_t setScaling(EScalingMode eScalingMode) {
+    return HwcService_Display_SetScaling(mHwcConn, mDisplay,
+                                         (EHwcsScalingMode)eScalingMode);
+  }
+
+  // Get last set scaling.
+  // Returns OK if succesful.
+  // Returns INVALID_OPERATION if scaling has not been set and eScalingMode is
+  // untouched.
+  status_t getScaling(EScalingMode *eScalingMode) {
+    return HwcService_Display_GetScaling(mHwcConn, mDisplay,
+                                         (EHwcsScalingMode *)eScalingMode);
+  }
+
+ private:
+  HwcServiceConnection mHwcConn;
+  uint32_t mDisplay;
+};
+
+}  // namespace hwcomposer
+
+#endif  // OS_ANDROID_IDISPLAY_SCALING_CONTROL_H_
diff --git a/os/android/libhwcservice/iservice.cpp b/os/android/libhwcservice/iservice.cpp
new file mode 100644 (file)
index 0000000..d7cf9b9
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// 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 "iservice.h"
+#include "icontrols.h"
+#include "idiagnostic.h"
+
+#include <utils/String8.h>
+
+namespace hwcomposer {
+
+using namespace android;
+
+/**
+ */
+class BpService : public BpInterface<IService> {
+ public:
+  BpService(const sp<IBinder>& impl) : BpInterface<IService>(impl) {
+  }
+
+  enum {
+    // ==============================================
+    // Public APIs - try not to reorder these
+
+    GET_HWC_VERSION = IBinder::FIRST_CALL_TRANSACTION,
+
+    // Dump options and current settings to logcat.
+    DUMP_OPTIONS,
+
+    // Override an option.
+    SET_OPTION,
+
+    // Disable hwc logviewer output to logcat
+    DISABLE_LOG_TO_LOGCAT = 98,
+    // Enable hwclogviewer output to logcat
+    ENABLE_LOG_TO_LOGCAT = 99,
+
+    // accessor for IBinder interface functions
+    TRANSACT_GET_DIAGNOSTIC = 100,
+    TRANSACT_GET_CONTROLS,
+  };
+
+  virtual String8 getHwcVersion() {
+    Parcel data, reply;
+    data.writeInterfaceToken(IService::getInterfaceDescriptor());
+    remote()->transact(GET_HWC_VERSION, data, &reply);
+    String8 ret = reply.readString8();
+    return ret;
+  }
+
+  virtual void dumpOptions(void) {
+    Parcel data, reply;
+    remote()->transact(DUMP_OPTIONS, data, &reply);
+  }
+
+  virtual status_t setOption(String8 option, String8 optionValue) {
+    Parcel data, reply;
+    data.writeInterfaceToken(IService::getInterfaceDescriptor());
+    data.writeString16(String16(option));
+    data.writeString16(String16(optionValue));
+    remote()->transact(SET_OPTION, data, &reply);
+    status_t ret = reply.readInt32();
+    return ret;
+  }
+
+  virtual status_t enableLogviewToLogcat(bool enable = true) {
+    Parcel data, reply;
+    data.writeInterfaceToken(IService::getInterfaceDescriptor());
+    if (enable) {
+      remote()->transact(ENABLE_LOG_TO_LOGCAT, data, &reply);
+    } else {
+      remote()->transact(DISABLE_LOG_TO_LOGCAT, data, &reply);
+    }
+    status_t ret = reply.readInt32();
+    return ret;
+  }
+
+  virtual sp<IDiagnostic> getDiagnostic() {
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(getInterfaceDescriptor());
+    status_t ret = remote()->transact(TRANSACT_GET_DIAGNOSTIC, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+    }
+    return interface_cast<IDiagnostic>(reply.readStrongBinder());
+  }
+
+  virtual sp<IControls> getControls() {
+    Parcel data;
+    Parcel reply;
+    data.writeInterfaceToken(getInterfaceDescriptor());
+    status_t ret = remote()->transact(TRANSACT_GET_CONTROLS, data, &reply);
+    if (ret != NO_ERROR) {
+      ALOGW("%s() transact failed: %d", __FUNCTION__, ret);
+    }
+    return interface_cast<IControls>(reply.readStrongBinder());
+  }
+};
+
+IMPLEMENT_META_INTERFACE(Service, "ia.hwc.IService");
+
+status_t BnService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+                               uint32_t flags) {
+  switch (code) {
+    case BpService::GET_HWC_VERSION: {
+      CHECK_INTERFACE(IService, data, reply);
+      reply->writeString8(getHwcVersion());
+      return NO_ERROR;
+    }
+
+    case BpService::SET_OPTION: {
+      CHECK_INTERFACE(IService, data, reply);
+      String16 option = data.readString16();
+      String16 optionValue = data.readString16();
+      status_t ret = setOption(String8(option), String8(optionValue));
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+
+    case BpService::DUMP_OPTIONS: {
+      CHECK_INTERFACE(IService, data, reply);
+      dumpOptions();
+      return NO_ERROR;
+    }
+
+    case BpService::DISABLE_LOG_TO_LOGCAT: {
+      CHECK_INTERFACE(IService, data, reply);
+      status_t ret = enableLogviewToLogcat(false);
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+
+    case BpService::ENABLE_LOG_TO_LOGCAT: {
+      CHECK_INTERFACE(IService, data, reply);
+      status_t ret = enableLogviewToLogcat();
+      reply->writeInt32(ret);
+      return NO_ERROR;
+    }
+
+    case BpService::TRANSACT_GET_DIAGNOSTIC: {
+      CHECK_INTERFACE(IService, data, reply);
+      sp<IBinder> b = IInterface::asBinder(this->getDiagnostic());
+      reply->writeStrongBinder(b);
+      return NO_ERROR;
+    }
+
+    case BpService::TRANSACT_GET_CONTROLS: {
+      CHECK_INTERFACE(IService, data, reply);
+      sp<IBinder> b = IInterface::asBinder(this->getControls());
+      reply->writeStrongBinder(b);
+      return NO_ERROR;
+    }
+
+    default:
+      return BBinder::onTransact(code, data, reply, flags);
+  }
+}
+
+}  // namespace hwcomposer
diff --git a/os/android/libhwcservice/iservice.h b/os/android/libhwcservice/iservice.h
new file mode 100644 (file)
index 0000000..29908a9
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// 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.
+*/
+
+#ifndef OS_ANDROID_ISERVICE_H_
+#define OS_ANDROID_ISERVICE_H_
+
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+#define IA_HWC_SERVICE_NAME "hwc.info"
+
+namespace hwcomposer {
+
+class IControls;
+class IDiagnostic;
+
+using namespace android;
+
+/** Maintenance interface to control HWC activity.
+ */
+class IService : public IInterface {
+ public:
+  DECLARE_META_INTERFACE(Service);
+
+  virtual sp<IDiagnostic> getDiagnostic() = 0;
+  virtual sp<IControls> getControls() = 0;
+
+  virtual String8 getHwcVersion() = 0;
+  virtual void dumpOptions(void) = 0;
+  virtual status_t setOption(String8 option, String8 optionValue) = 0;
+  virtual status_t enableLogviewToLogcat(bool enable = true) = 0;
+};
+
+/**
+ */
+class BnService : public BnInterface<IService> {
+ public:
+  virtual status_t onTransact(uint32_t, const Parcel&, Parcel*, uint32_t);
+};
+
+}  // namespace hwcomposer
+
+#endif  // OS_ANDROID_ISERVICE_H_
index aa9b779..7310ec0 100644 (file)
@@ -186,7 +186,10 @@ struct HwcLayer {
     return state_ & kLayerValidated;
   }
 
-  void SetLayerZOrder(uint32_t order);
+  /**
+   * API for setting ZOrder for this layer.
+   */
+  void SetLayerZOrder(uint32_t z_order);
 
  private:
   void Validate();