power: Prepare for power profile support

 * Add support for system performance profiles and CPU boost.
 * Uses mpctl to configure the CPUs in the appropriate modes.
 * Implement binderized Lineage power HAL.

Author: Steve Kondik <shade@chemlab.org>
Date:   Sat May 17 03:37:53 2014 -0700

    power: Add support for CPU boost hint

    Change-Id: I07c3e8daf8a5f3b568e27334f26d4ba8f4cf40c4

Author: Steve Kondik <shade@chemlab.org>
Date:   Sun May 18 23:55:23 2014 -0700

    power: Add power hint to set profile

     * A PowerHAL can implement support for this hint to receive
       power profile changes from the framework.

    Change-Id: Ie1e9e3b827c731cf5a817a0491677e3451fe8678

Author: Steve Kondik <shade@chemlab.org>
Date:   Mon May 19 17:26:34 2014 -0700

    power: Add support for SET_PROFILE hints

     * Add support for system performance profiles.
     * Uses mpctl to configure the CPUs in the appropriate modes.
     * PERFORMANCE = all cores at max
     * POWER_SAVE = max two cores at non-turbo voltage
     * If a custom profile is set, don't honor any other hints
     * Clean up the code and firm up the locking.

    Change-Id: Ie6acada805780c9ae6e6bc2002843aef638ca63b

Author: Steve Kondik <steve@cyngn.com>
Date:   Tue Nov 3 03:27:42 2015 -0800

    power: Update for PerformanceManager changes

     * Undo damage caused by the previous patch which broke
       all hint arguments. We were actually using these wrong to
       begin with anyway.
     * Add support for get_profile
     * Clean up code

    Change-Id: Ibc3f21bfb7aa46ec97b9b63d09737d4331a5a714

Author: dianlujitao <dianlujitao@lineageos.org>
Date:   Sat Feb 23 20:24:57 2019 +0800

    power: Pass NULL parameter in powerHint if data is zero

     * This restores the behavior in AOSP and CAF power HAL to avoid
       confusion.

    Change-Id: I72f5bb9286e2f57121e39eea82d2fe8854989393

Change-Id: I7ae614667e3182eaf0a90b81e8ed839689cfbf28
diff --git a/Android.mk b/Android.mk
index 5335a67..9fe5f27 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,3 +1,31 @@
+# Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+# Copyright (C) 2017-2019 The LineageOS Project
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+# *    * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+#       copyright notice, this list of conditions and the following
+#       disclaimer in the documentation and/or other materials provided
+#       with the distribution.
+#     * Neither the name of The Linux Foundation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
 LOCAL_PATH := $(call my-dir)
 
 ifeq ($(call is-vendor-board-platform,QCOM),true)
@@ -15,7 +43,8 @@
     libhidltransport \
     libhwbinder \
     libutils \
-    android.hardware.power@1.2
+    android.hardware.power@1.2 \
+    vendor.lineage.power@1.0
 
 LOCAL_HEADER_LIBRARIES := \
     libhardware_headers
diff --git a/Power.cpp b/Power.cpp
index 19e3abe..ba8af81 100644
--- a/Power.cpp
+++ b/Power.cpp
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2017-2019 The LineageOS Project
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -29,6 +30,8 @@
 
 #define LOG_TAG "android.hardware.power@1.2-service-qti"
 
+// #define LOG_NDEBUG 0
+
 #include "Power.h"
 #include <android-base/file.h>
 #include <log/log.h>
@@ -101,6 +104,36 @@
     return powerHint(static_cast<PowerHint_1_0>(hint), data);
 }
 
+Return<int32_t> Power::getFeature(LineageFeature feature) {
+    if (feature == LineageFeature::SUPPORTED_PROFILES) {
+        return get_number_of_profiles();
+    }
+    return -1;
+}
+
+status_t Power::registerAsSystemService() {
+    status_t ret = 0;
+
+    ret = IPower::registerAsService();
+    if (ret != 0) {
+        ALOGE("Failed to register IPower (%d)", ret);
+        goto fail;
+    } else {
+        ALOGI("Successfully registered IPower");
+    }
+
+    ret = ILineagePower::registerAsService();
+    if (ret != 0) {
+        ALOGE("Failed to register ILineagePower (%d)", ret);
+        goto fail;
+    } else {
+        ALOGI("Successfully registered ILineagePower");
+    }
+
+fail:
+    return ret;
+}
+
 }  // namespace implementation
 }  // namespace V1_2
 }  // namespace power
diff --git a/Power.h b/Power.h
index 4ede54b..a76c65d 100644
--- a/Power.h
+++ b/Power.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2017-2019 The LineageOS Project
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -34,6 +35,7 @@
 #include <hardware/power.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
+#include <vendor/lineage/power/1.0/ILineagePower.h>
 
 namespace android {
 namespace hardware {
@@ -47,11 +49,14 @@
 using ::android::hardware::Return;
 using ::android::hardware::Void;
 using ::android::hardware::power::V1_2::IPower;
+using ::vendor::lineage::power::V1_0::ILineagePower;
+using ::vendor::lineage::power::V1_0::LineageFeature;
 
-struct Power : public IPower {
+struct Power : public IPower, public ILineagePower {
     // Methods from ::android::hardware::power::V1_0::IPower follow.
 
     Power();
+    status_t registerAsSystemService();
 
     Return<void> setInteractive(bool interactive) override;
     Return<void> powerHint(PowerHint_1_0 hint, int32_t data) override;
@@ -63,6 +68,9 @@
     Return<void> powerHintAsync(PowerHint_1_0 hint, int32_t data) override;
     // Methods from ::android::hardware::power::V1_2::IPower follow
     Return<void> powerHintAsync_1_2(PowerHint_1_2 hint, int32_t data) override;
+
+    // Methods from ::vendor::lineage::power::V1_0::ILineagePower follow.
+    Return<int32_t> getFeature(LineageFeature feature) override;
 };
 
 }  // namespace implementation
diff --git a/hint-data.h b/hint-data.h
index 629a01e..b6521c1 100644
--- a/hint-data.h
+++ b/hint-data.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012, 2013, 2015, 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2018-2019 The LineageOS Project
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -54,6 +55,8 @@
 
 #define VR_MODE_SUSTAINED_PERF_HINT (0x1301)
 
+#define DEFAULT_PROFILE_HINT_ID (0xFF00)
+
 struct hint_handles {
     int handle;
     int ref_count;
diff --git a/power-common.c b/power-common.c
index cdac1e6..2c8495f 100644
--- a/power-common.c
+++ b/power-common.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2017-2019 The LineageOS Project
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -93,11 +94,18 @@
                 }
             }
             break;
+        case POWER_HINT_SET_PROFILE:
+            ALOGI("set profile power hint not handled in power_hint_override");
+            break;
         default:
             break;
     }
 }
 
+int __attribute__((weak)) get_number_of_profiles() {
+    return 0;
+}
+
 int __attribute__((weak)) set_interactive_override(int UNUSED(on)) {
     return HINT_NONE;
 }
diff --git a/power-common.h b/power-common.h
index a0413b9..9fc1546 100644
--- a/power-common.h
+++ b/power-common.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2013, 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2017-2019 The LineageOS Project
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -43,14 +44,26 @@
 
 enum CPU_GOV_CHECK { CPU0 = 0, CPU1 = 1, CPU2 = 2, CPU3 = 3 };
 
+enum {
+    PROFILE_POWER_SAVE = 0,
+    PROFILE_BALANCED,
+    PROFILE_HIGH_PERFORMANCE,
+    PROFILE_BIAS_POWER,
+    PROFILE_BIAS_PERFORMANCE
+};
+
 void power_init(void);
 void power_hint(power_hint_t hint, void* data);
 void set_interactive(int on);
+int get_number_of_profiles();
 
 #define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
 #define CHECK_HANDLE(x) ((x) > 0)
 #define UNUSED(x) UNUSED_##x __attribute__((__unused__))
 
+// Custom Lineage hints
+const static power_hint_t POWER_HINT_SET_PROFILE = (power_hint_t)0x00000111;
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/service.cpp b/service.cpp
index 85f84d1..ed9ada4 100644
--- a/service.cpp
+++ b/service.cpp
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2017-2019 The LineageOS Project
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -29,6 +30,8 @@
 
 #define LOG_TAG "android.hardware.power@1.2-service-qti"
 
+// #define LOG_NDEBUG 0
+
 #include <hardware/power.h>
 #include <hidl/HidlTransportSupport.h>
 #ifdef ARCH_ARM_32
@@ -46,7 +49,6 @@
 using android::hardware::joinRpcThreadpool;
 
 // Generated HIDL files
-using android::hardware::power::V1_2::IPower;
 using android::hardware::power::V1_2::implementation::Power;
 
 int main() {
@@ -55,7 +57,7 @@
 #endif
 
     status_t status;
-    android::sp<IPower> service = nullptr;
+    android::sp<Power> service = nullptr;
 
     ALOGI("Power HAL Service 1.2 is starting.");
 
@@ -68,7 +70,7 @@
 
     configureRpcThreadpool(1, true /*callerWillJoin*/);
 
-    status = service->registerAsService();
+    status = service->registerAsSystemService();
     if (status != OK) {
         ALOGE("Could not register service for Power HAL(%d).", status);
         goto shutdown;