Merge 7f664a2f8392c966daa254b96270ba7ed748c2a5 on remote branch

Change-Id: Ic447ce40f44fdc28d5c45b7c4b102e9715a80c90
diff --git a/include/layer_extn_intf.h b/include/layer_extn_intf.h
index 04cbc98..adf36bb 100644
--- a/include/layer_extn_intf.h
+++ b/include/layer_extn_intf.h
@@ -50,6 +50,7 @@
  public:
   virtual ~LayerExtnIntf() = default;
   virtual int GetLayerClass(const std::string &name) = 0;
+  virtual void UpdateLayerState(const std::vector<std::string> &layers, int num_layers) = 0;
 };
 
 typedef bool (*CreateLayerExtnInterface)(uint16_t version, LayerExtnIntf **interface);
diff --git a/services/config/config_defs.h b/services/config/config_defs.h
index 7b4838a..c4181b8 100644
--- a/services/config/config_defs.h
+++ b/services/config/config_defs.h
@@ -48,6 +48,7 @@
   kPrimary,
   kExternal,
   kVirtual,
+  kBuiltIn2,
 };
 
 enum class ExternalStatus : int {
@@ -90,6 +91,13 @@
   kWaitForCommitEachFrame,
 };
 
+enum class TUIEventType : int {
+  kNone,
+  kPrepareTUITransition,
+  kStartTUITransition,
+  kEndTUITransition,
+};
+
 // Input and Output Params structures
 struct Attributes {
   uint32_t vsync_period = 0;
@@ -219,6 +227,11 @@
   int qsync_refresh_rate = 0;
 };
 
+struct TUIEventParams {
+  DisplayType dpy = DisplayType::kInvalid;
+  TUIEventType tui_event_type = TUIEventType::kNone;
+};
+
 /* Callback Interface */
 class ConfigCallback {
  public:
@@ -281,6 +294,7 @@
   virtual int IsSmartPanelConfig(uint32_t disp_id, uint32_t config_id, bool *is_smart) DEFAULT_RET
   virtual int IsRotatorSupportedFormat(int hal_format, bool ubwc, bool *supported) DEFAULT_RET
   virtual int ControlQsyncCallback(bool enable) DEFAULT_RET
+  virtual int SendTUIEvent(DisplayType dpy, TUIEventType event_type) DEFAULT_RET
 
   // deprecated APIs
   virtual int GetDebugProperty(const std::string prop_name, std::string value) DEFAULT_RET
diff --git a/services/config/src/client_impl.cpp b/services/config/src/client_impl.cpp
index c11fa3c..0e1cdab 100644
--- a/services/config/src/client_impl.cpp
+++ b/services/config/src/client_impl.cpp
@@ -47,13 +47,25 @@
     handle = client_handle;
   };
   int pid = getpid();
-  display_config_->registerClient(client_name + std::to_string(pid), this, hidl_callback);
+  android::sp<ClientCallback> client_cb(new ClientCallback(callback));
+  display_config_->registerClient(client_name + std::to_string(pid), client_cb,
+                                  hidl_callback);
   client_handle_ = handle;
-  callback_ = callback;
 
   return 0;
 }
 
+void ClientImpl::DeInit() {
+  int32_t error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kDestroy, {}, {}, hidl_cb);
+  display_config_.clear();
+  display_config_ = nullptr;
+}
+
 int ClientImpl::IsDisplayConnected(DisplayType dpy, bool *connected) {
   ByteStream input_params;
   input_params.setToExternal(reinterpret_cast<uint8_t*>(&dpy), sizeof(DisplayType));
@@ -623,10 +635,6 @@
 
 int ClientImpl::SetCWBOutputBuffer(uint32_t disp_id, const Rect rect, bool post_processed,
                                    const native_handle_t *buffer) {
-  if (callback_ == nullptr) {
-    return -EINVAL;
-  }
-
   struct CwbBufferParams input = {disp_id, rect, post_processed};
   ByteStream input_params;
   input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct CwbBufferParams));
@@ -820,11 +828,25 @@
   return error;
 }
 
-void ClientImpl::ParseNotifyCWBBufferDone(const ByteStream &input_params,
-                                          const HandleStream &input_handles) {
+int ClientImpl::SendTUIEvent(DisplayType dpy, TUIEventType event_type) {
+  struct TUIEventParams input = {dpy, event_type};
+  ByteStream input_params;
+  input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct TUIEventParams));
+  int32_t error = 0;
+  auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
+    error = err;
+  };
+
+  display_config_->perform(client_handle_, kSendTUIEvent, input_params, {}, hidl_cb);
+
+  return error;
+}
+
+void ClientCallback::ParseNotifyCWBBufferDone(const ByteStream &input_params,
+                                              const HandleStream &input_handles) {
   const int *error;
 
-  if (input_params.size() == 0 || input_handles.size() == 0) {
+  if (callback_ == nullptr || input_params.size() == 0 || input_handles.size() == 0) {
     return;
   }
 
@@ -834,10 +856,10 @@
   callback_->NotifyCWBBufferDone(*error, buffer.getNativeHandle());
 }
 
-void ClientImpl::ParseNotifyQsyncChange(const ByteStream &input_params) {
+void ClientCallback::ParseNotifyQsyncChange(const ByteStream &input_params) {
   const struct QsyncCallbackParams *qsync_data;
 
-  if (input_params.size() == 0) {
+  if (callback_ == nullptr || input_params.size() == 0) {
     return;
   }
 
@@ -847,8 +869,8 @@
                                qsync_data->qsync_refresh_rate);
 }
 
-Return<void> ClientImpl::perform(uint32_t op_code, const ByteStream &input_params,
-                                 const HandleStream &input_handles) {
+Return<void> ClientCallback::perform(uint32_t op_code, const ByteStream &input_params,
+                                     const HandleStream &input_handles) {
   switch (op_code) {
     case kSetCwbOutputBuffer:
       ParseNotifyCWBBufferDone(input_params, input_handles);
diff --git a/services/config/src/client_impl.h b/services/config/src/client_impl.h
index 085fc22..a76d3de 100644
--- a/services/config/src/client_impl.h
+++ b/services/config/src/client_impl.h
@@ -50,9 +50,24 @@
 typedef hidl_vec<uint8_t> ByteStream;
 typedef hidl_vec<hidl_handle> HandleStream;
 
-class ClientImpl : public ClientInterface, public IDisplayConfigCallback {
+class ClientCallback: public IDisplayConfigCallback {
+ public:
+  ClientCallback(ConfigCallback *cb) {
+    callback_ = cb;
+  }
+
+ private:
+  virtual Return<void> perform(uint32_t op_code, const ByteStream &input_params,
+                               const HandleStream &input_handles);
+  void ParseNotifyCWBBufferDone(const ByteStream &input_params, const HandleStream &input_handles);
+  void ParseNotifyQsyncChange(const ByteStream &input_params);
+  ConfigCallback *callback_ = nullptr;
+};
+
+class ClientImpl : public ClientInterface {
  public:
   int Init(std::string client_name, ConfigCallback *callback);
+  void DeInit();
 
   virtual int IsDisplayConnected(DisplayType dpy, bool *connected);
   virtual int SetDisplayStatus(DisplayType dpy, ExternalStatus status);
@@ -99,14 +114,10 @@
   virtual int IsSmartPanelConfig(uint32_t disp_id, uint32_t config_id, bool *is_smart);
   virtual int IsRotatorSupportedFormat(int hal_format, bool ubwc, bool *supported);
   virtual int ControlQsyncCallback(bool enable);
+  virtual int SendTUIEvent(DisplayType dpy, TUIEventType event_type);
 
  private:
-  virtual Return<void> perform(uint32_t op_code, const ByteStream &input_params,
-                               const HandleStream &input_handles);
-  void ParseNotifyCWBBufferDone(const ByteStream &input_params, const HandleStream &input_handles);
-  void ParseNotifyQsyncChange(const ByteStream &input_params);
   android::sp<IDisplayConfig> display_config_ = nullptr;
-  ConfigCallback *callback_ = nullptr;
   uint64_t client_handle_ = 0;
 };
 
diff --git a/services/config/src/client_interface.cpp b/services/config/src/client_interface.cpp
index 94be1b9..9c9ecd2 100644
--- a/services/config/src/client_interface.cpp
+++ b/services/config/src/client_interface.cpp
@@ -56,7 +56,9 @@
 
 void ClientInterface::Destroy(ClientInterface *intf) {
   if (intf) {
-    delete static_cast<ClientImpl *>(intf);
+    ClientImpl *impl = static_cast<ClientImpl *>(intf);
+    impl->DeInit();
+    delete impl;
   }
 }
 
diff --git a/services/config/src/device_impl.cpp b/services/config/src/device_impl.cpp
index 8d036cd..5a590a8 100644
--- a/services/config/src/device_impl.cpp
+++ b/services/config/src/device_impl.cpp
@@ -96,8 +96,11 @@
   }
 }
 
-DeviceImpl::DeviceClientContext::DeviceClientContext(const sp<IDisplayConfigCallback> callback) {
-  callback_ = callback;
+DeviceImpl::DeviceClientContext::DeviceClientContext(
+            const sp<IDisplayConfigCallback> callback) : callback_(callback) { }
+
+sp<IDisplayConfigCallback> DeviceImpl::DeviceClientContext::GetDeviceConfigCallback() {
+  return callback_;
 }
 
 void DeviceImpl::DeviceClientContext::SetDeviceConfigIntf(ConfigInterface *intf) {
@@ -575,6 +578,10 @@
   int32_t error = intf_->GetSupportedDSIBitClks(*disp_id, &bit_clks);
 
   bit_clks_data = reinterpret_cast<uint64_t *>(malloc(sizeof(uint64_t) * bit_clks.size()));
+  if (bit_clks_data == NULL) {
+    _hidl_cb(-EINVAL, {}, {});
+    return;
+  }
   for (int i = 0; i < bit_clks.size(); i++) {
     bit_clks_data[i] = bit_clks[i];
   }
@@ -686,6 +693,36 @@
   _hidl_cb(error, {}, {});
 }
 
+void DeviceImpl::DeviceClientContext::ParseSendTUIEvent(const ByteStream &input_params,
+                                                        perform_cb _hidl_cb) {
+  const struct TUIEventParams *input_data =
+               reinterpret_cast<const TUIEventParams*>(input_params.data());
+
+  int32_t error = intf_->SendTUIEvent(input_data->dpy, input_data->tui_event_type);
+
+  _hidl_cb(error, {}, {});
+}
+
+void DeviceImpl::ParseDestroy(uint64_t client_handle, perform_cb _hidl_cb) {
+  auto itr = display_config_map_.find(client_handle);
+  if (itr == display_config_map_.end()) {
+    _hidl_cb(-EINVAL, {}, {});
+    return;
+  }
+
+  std::shared_ptr<DeviceClientContext> client = itr->second;
+  if (client != NULL) {
+    sp<IDisplayConfigCallback> callback = client->GetDeviceConfigCallback();
+    callback->unlinkToDeath(this);
+    ConfigInterface *intf = client->GetDeviceConfigIntf();
+    intf_->UnRegisterClientContext(intf);
+    client.reset();
+    display_config_map_.erase(itr);
+  }
+
+  _hidl_cb(0, {}, {});
+}
+
 Return<void> DeviceImpl::perform(uint64_t client_handle, uint32_t op_code,
                                  const ByteStream &input_params, const HandleStream &input_handles,
                                  perform_cb _hidl_cb) {
@@ -830,6 +867,12 @@
     case kControlQsyncCallback:
       client->ParseControlQsyncCallback(client_handle, input_params, _hidl_cb);
       break;
+    case kSendTUIEvent:
+      client->ParseSendTUIEvent(input_params, _hidl_cb);
+      break;
+    case kDestroy:
+      ParseDestroy(client_handle, _hidl_cb);
+      break;
     default:
       break;
   }
diff --git a/services/config/src/device_impl.h b/services/config/src/device_impl.h
index 96e9351..39b7587 100644
--- a/services/config/src/device_impl.h
+++ b/services/config/src/device_impl.h
@@ -66,6 +66,7 @@
 
     void SetDeviceConfigIntf(ConfigInterface *intf);
     ConfigInterface* GetDeviceConfigIntf();
+    sp<IDisplayConfigCallback> GetDeviceConfigCallback();
 
     virtual void NotifyCWBBufferDone(int32_t error, const native_handle_t *buffer);
     virtual void NotifyQsyncChange(bool qsync_enabled, int32_t refresh_rate,
@@ -115,10 +116,11 @@
     void ParseIsRotatorSupportedFormat(const ByteStream &input_params, perform_cb _hidl_cb);
     void ParseControlQsyncCallback(uint64_t client_handle, const ByteStream &input_params,
                                    perform_cb _hidl_cb);
+    void ParseSendTUIEvent(const ByteStream &input_params, perform_cb _hidl_cb);
 
    private:
     ConfigInterface *intf_ = nullptr;
-    sp<IDisplayConfigCallback> callback_;
+    const sp<IDisplayConfigCallback> callback_;
   };
 
   Return<void> registerClient(const hidl_string &client_name, const sp<IDisplayConfigCallback>& cb,
@@ -127,6 +129,7 @@
                        const HandleStream &input_handles, perform_cb _hidl_cb) override;
   void serviceDied(uint64_t client_handle,
                    const android::wp<::android::hidl::base::V1_0::IBase>& callback);
+  void ParseDestroy(uint64_t client_handle, perform_cb _hidl_cb);
 
   ClientContext *intf_ = nullptr;
   std::map<uint64_t, std::shared_ptr<DeviceClientContext>> display_config_map_;
diff --git a/services/config/src/opcode_types.h b/services/config/src/opcode_types.h
index 1b28105..b589d8a 100644
--- a/services/config/src/opcode_types.h
+++ b/services/config/src/opcode_types.h
@@ -75,6 +75,9 @@
   kCreateVirtualDisplay = 39,
   kIsRotatorSupportedFormat = 40,
   kControlQsyncCallback = 41,
+  kSendTUIEvent = 42,
+
+  kDestroy = 0xFFFF, // Destroy sequence execution
 };
 
 }  // namespace DisplayConfig