Revert "Revert "transcoding: add thermal status listener""

This reverts commit b253cec66de2986379ef94e1d372123dee1b826f.

Reason for revert: reland with fix

Change-Id: Ieab554dc2dc4187e75fc223997387f4875832e52
diff --git a/media/libmediatranscoding/TranscodingThermalPolicy.cpp b/media/libmediatranscoding/TranscodingThermalPolicy.cpp
new file mode 100644
index 0000000..9984abe
--- /dev/null
+++ b/media/libmediatranscoding/TranscodingThermalPolicy.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "TranscodingThermalPolicy"
+
+#include <media/TranscodingThermalPolicy.h>
+#include <media/TranscodingUidPolicy.h>
+#include <utils/Log.h>
+
+namespace android {
+
+static bool needThrottling(AThermalStatus status) {
+    return (status >= ATHERMAL_STATUS_SEVERE);
+}
+
+//static
+void TranscodingThermalPolicy::onStatusChange(void* data, AThermalStatus status) {
+    TranscodingThermalPolicy* policy = static_cast<TranscodingThermalPolicy*>(data);
+    policy->onStatusChange(status);
+}
+
+TranscodingThermalPolicy::TranscodingThermalPolicy()
+      : mRegistered(false), mThermalManager(nullptr), mIsThrottling(false) {
+    registerSelf();
+}
+
+TranscodingThermalPolicy::~TranscodingThermalPolicy() {
+    unregisterSelf();
+}
+
+void TranscodingThermalPolicy::registerSelf() {
+    ALOGI("TranscodingThermalPolicy: registerSelf");
+
+    std::scoped_lock lock{mRegisteredLock};
+
+    if (mRegistered) {
+        return;
+    }
+
+    if (__builtin_available(android __TRANSCODING_MIN_API__, *)) {
+        AThermalManager* thermalManager = AThermal_acquireManager();
+        if (thermalManager == nullptr) {
+            ALOGE("Failed to acquire thermal manager");
+            return;
+        }
+
+        int ret = AThermal_registerThermalStatusListener(thermalManager, onStatusChange, this);
+        if (ret != 0) {
+            ALOGE("Failed to register thermal status listener");
+            AThermal_releaseManager(thermalManager);
+            return;
+        }
+
+        mIsThrottling = needThrottling(AThermal_getCurrentThermalStatus(thermalManager));
+        mThermalManager = thermalManager;
+    }
+
+    mRegistered = true;
+}
+
+void TranscodingThermalPolicy::unregisterSelf() {
+    ALOGI("TranscodingThermalPolicy: unregisterSelf");
+
+    std::scoped_lock lock{mRegisteredLock};
+
+    if (!mRegistered) {
+        return;
+    }
+
+    if (__builtin_available(android __TRANSCODING_MIN_API__, *)) {
+        if (mThermalManager != nullptr) {
+            // Unregister listener
+            int ret =
+                    AThermal_unregisterThermalStatusListener(mThermalManager, onStatusChange, this);
+            if (ret != 0) {
+                ALOGW("Failed to unregister thermal status listener");
+            }
+            AThermal_releaseManager(mThermalManager);
+            mThermalManager = nullptr;
+        }
+    }
+
+    mRegistered = false;
+}
+
+void TranscodingThermalPolicy::setCallback(
+        const std::shared_ptr<ThermalPolicyCallbackInterface>& cb) {
+    std::scoped_lock lock{mCallbackLock};
+    mThermalPolicyCallback = cb;
+}
+
+bool TranscodingThermalPolicy::getThrottlingStatus() {
+    std::scoped_lock lock{mRegisteredLock};
+    return mIsThrottling;
+}
+
+void TranscodingThermalPolicy::onStatusChange(AThermalStatus status) {
+    bool isThrottling = needThrottling(status);
+
+    {
+        std::scoped_lock lock{mRegisteredLock};
+        if (isThrottling == mIsThrottling) {
+            return;
+        }
+        ALOGI("Transcoding thermal throttling changed: %d", isThrottling);
+        mIsThrottling = isThrottling;
+    }
+
+    std::scoped_lock lock{mCallbackLock};
+    std::shared_ptr<ThermalPolicyCallbackInterface> cb;
+    if ((cb = mThermalPolicyCallback.lock()) != nullptr) {
+        if (isThrottling) {
+            cb->onThrottlingStarted();
+        } else {
+            cb->onThrottlingStopped();
+        }
+    }
+}
+}  // namespace android