summaryrefslogtreecommitdiff
path: root/native
diff options
context:
space:
mode:
Diffstat (limited to 'native')
-rw-r--r--native/android/Android.bp6
-rw-r--r--native/android/TEST_MAPPING19
-rw-r--r--native/android/configuration.cpp2
-rw-r--r--native/android/libandroid.map.txt3
-rw-r--r--native/android/performance_hint.cpp24
-rw-r--r--native/android/system_fonts.cpp9
-rw-r--r--native/android/tests/performance_hint/PerformanceHintNativeTest.cpp62
-rw-r--r--native/android/tests/thermal/Android.bp65
-rw-r--r--native/android/tests/thermal/NativeThermalUnitTest.cpp158
-rw-r--r--native/android/tests/thermal/OWNERS1
-rw-r--r--native/android/thermal.cpp124
-rw-r--r--native/webview/TEST_MAPPING2
12 files changed, 429 insertions, 46 deletions
diff --git a/native/android/Android.bp b/native/android/Android.bp
index 254eb4494ed8..7f3792d06795 100644
--- a/native/android/Android.bp
+++ b/native/android/Android.bp
@@ -46,7 +46,10 @@ cc_defaults {
cc_library_shared {
name: "libandroid",
- defaults: ["libandroid_defaults"],
+ defaults: [
+ "libandroid_defaults",
+ "android.hardware.power-ndk_shared",
+ ],
srcs: [
"activity_manager.cpp",
@@ -95,7 +98,6 @@ cc_library_shared {
"libpowermanager",
"android.hardware.configstore@1.0",
"android.hardware.configstore-utils",
- "android.hardware.power-V4-ndk",
"libnativedisplay",
],
diff --git a/native/android/TEST_MAPPING b/native/android/TEST_MAPPING
index 6a5d2c008b1d..7c710982e4f6 100644
--- a/native/android/TEST_MAPPING
+++ b/native/android/TEST_MAPPING
@@ -12,6 +12,25 @@
}
],
"file_patterns": ["permission_manager.cpp"]
+ },
+ {
+ "name": "CtsOsTestCases",
+ "options": [
+ {
+ "include-filter": "android.os.cts.PerformanceHintManagerTest"
+ }
+ ],
+ "file_patterns": ["performance_hint.cpp"]
+ }
+ ],
+ "postsubmit": [
+ {
+ "name": "CtsThermalTestCases",
+ "file_patterns": ["thermal.cpp"]
+ },
+ {
+ "name": "NativeThermalUnitTestCases",
+ "file_patterns": ["thermal.cpp"]
}
]
}
diff --git a/native/android/configuration.cpp b/native/android/configuration.cpp
index b50514d27bac..283445fc8a9a 100644
--- a/native/android/configuration.cpp
+++ b/native/android/configuration.cpp
@@ -36,7 +36,7 @@ void AConfiguration_delete(AConfiguration* config) {
void AConfiguration_fromAssetManager(AConfiguration* out, AAssetManager* am) {
ScopedLock<AssetManager2> locked_mgr(*AssetManagerForNdkAssetManager(am));
- ResTable_config config = locked_mgr->GetConfiguration();
+ ResTable_config config = locked_mgr->GetConfigurations()[0];
// AConfiguration is not a virtual subclass, so we can memcpy.
memcpy(out, &config, sizeof(config));
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index d74f9b7bb659..fea6c5f95358 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -327,6 +327,7 @@ LIBANDROID {
AThermal_registerThermalStatusListener; # introduced=30
AThermal_unregisterThermalStatusListener; # introduced=30
AThermal_getThermalHeadroom; # introduced=31
+ AThermal_getThermalHeadroomThresholds; # introduced=VanillaIceCream
APerformanceHint_getManager; # introduced=Tiramisu
APerformanceHint_createSession; # introduced=Tiramisu
APerformanceHint_getPreferredUpdateRateNanos; # introduced=Tiramisu
@@ -334,12 +335,14 @@ LIBANDROID {
APerformanceHint_reportActualWorkDuration; # introduced=Tiramisu
APerformanceHint_closeSession; # introduced=Tiramisu
APerformanceHint_setThreads; # introduced=UpsideDownCake
+ APerformanceHint_setPreferPowerEfficiency; # introduced=VanillaIceCream
local:
*;
};
LIBANDROID_PLATFORM {
global:
+ AThermal_setIThermalServiceForTesting;
APerformanceHint_setIHintManagerForTesting;
APerformanceHint_sendHint;
APerformanceHint_getThreadIds;
diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp
index b3628fa3e5ce..c25df6e08fd0 100644
--- a/native/android/performance_hint.cpp
+++ b/native/android/performance_hint.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "perf_hint"
#include <aidl/android/hardware/power/SessionHint.h>
+#include <aidl/android/hardware/power/SessionMode.h>
#include <android/os/IHintManager.h>
#include <android/os/IHintSession.h>
#include <android/performance_hint.h>
@@ -36,6 +37,7 @@ using namespace android::os;
using namespace std::chrono_literals;
using AidlSessionHint = aidl::android::hardware::power::SessionHint;
+using AidlSessionMode = aidl::android::hardware::power::SessionMode;
struct APerformanceHintSession;
@@ -72,6 +74,7 @@ public:
int sendHint(SessionHint hint);
int setThreads(const int32_t* threadIds, size_t size);
int getThreadIds(int32_t* const threadIds, size_t* size);
+ int setPreferPowerEfficiency(bool enabled);
private:
friend struct APerformanceHintManager;
@@ -274,9 +277,10 @@ int APerformanceHintSession::setThreads(const int32_t* threadIds, size_t size) {
binder::Status ret = mHintManager->setHintSessionThreads(mHintSession, tids);
if (!ret.isOk()) {
ALOGE("%s: failed: %s", __FUNCTION__, ret.exceptionMessage().c_str());
- if (ret.exceptionCode() == binder::Status::Exception::EX_SECURITY ||
- ret.exceptionCode() == binder::Status::Exception::EX_ILLEGAL_ARGUMENT) {
+ if (ret.exceptionCode() == binder::Status::Exception::EX_ILLEGAL_ARGUMENT) {
return EINVAL;
+ } else if (ret.exceptionCode() == binder::Status::Exception::EX_SECURITY) {
+ return EPERM;
}
return EPIPE;
}
@@ -306,6 +310,18 @@ int APerformanceHintSession::getThreadIds(int32_t* const threadIds, size_t* size
return 0;
}
+int APerformanceHintSession::setPreferPowerEfficiency(bool enabled) {
+ binder::Status ret =
+ mHintSession->setMode(static_cast<int32_t>(AidlSessionMode::POWER_EFFICIENCY), enabled);
+
+ if (!ret.isOk()) {
+ ALOGE("%s: HintSession setPreferPowerEfficiency failed: %s", __FUNCTION__,
+ ret.exceptionMessage().c_str());
+ return EPIPE;
+ }
+ return OK;
+}
+
// ===================================== C API
APerformanceHintManager* APerformanceHint_getManager() {
return APerformanceHintManager::getInstance();
@@ -356,6 +372,10 @@ int APerformanceHint_getThreadIds(void* aPerformanceHintSession, int32_t* const
->getThreadIds(threadIds, size);
}
+int APerformanceHint_setPreferPowerEfficiency(APerformanceHintSession* session, bool enabled) {
+ return session->setPreferPowerEfficiency(enabled);
+}
+
void APerformanceHint_setIHintManagerForTesting(void* iManager) {
delete gHintManagerForTesting;
gHintManagerForTesting = nullptr;
diff --git a/native/android/system_fonts.cpp b/native/android/system_fonts.cpp
index ceab164aa324..91f78ce6f950 100644
--- a/native/android/system_fonts.cpp
+++ b/native/android/system_fonts.cpp
@@ -249,14 +249,15 @@ ASystemFontIterator* ASystemFontIterator_open() {
locale.emplace(minikin::getLocaleString(localeId));
}
std::vector<std::pair<uint32_t, float>> axes;
- for (const auto& [tag, value] : font->typeface()->GetAxes()) {
+ for (const auto& [tag, value] : font->baseTypeface()->GetAxes()) {
axes.push_back(std::make_pair(tag, value));
}
- fonts.insert({font->typeface()->GetFontPath(), std::move(locale),
+ fonts.insert({font->baseTypeface()->GetFontPath(), std::move(locale),
font->style().weight(),
font->style().slant() == minikin::FontStyle::Slant::ITALIC,
- static_cast<uint32_t>(font->typeface()->GetFontIndex()), axes});
+ static_cast<uint32_t>(font->baseTypeface()->GetFontIndex()),
+ axes});
}
});
@@ -321,7 +322,7 @@ AFont* _Nonnull AFontMatcher_match(
.font;
std::unique_ptr<AFont> result = std::make_unique<AFont>();
const android::MinikinFontSkia* minikinFontSkia =
- reinterpret_cast<android::MinikinFontSkia*>(font->typeface().get());
+ reinterpret_cast<android::MinikinFontSkia*>(font->baseTypeface().get());
result->mFilePath = minikinFontSkia->getFilePath();
result->mWeight = font->style().weight();
result->mItalic = font->style().slant() == minikin::FontStyle::Slant::ITALIC;
diff --git a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
index 791adfd33fcd..22d33b139ccf 100644
--- a/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
+++ b/native/android/tests/performance_hint/PerformanceHintNativeTest.cpp
@@ -56,7 +56,8 @@ public:
(const ::std::vector<int64_t>& actualDurationNanos,
const ::std::vector<int64_t>& timeStampNanos),
(override));
- MOCK_METHOD(Status, sendHint, (int32_t hints), (override));
+ MOCK_METHOD(Status, sendHint, (int32_t hint), (override));
+ MOCK_METHOD(Status, setMode, (int32_t mode, bool enabled), (override));
MOCK_METHOD(Status, close, (), (override));
MOCK_METHOD(IBinder*, onAsBinder, (), (override));
};
@@ -178,4 +179,63 @@ TEST_F(PerformanceHintTest, SetThreads) {
.WillOnce(Return(Status()));
result = APerformanceHint_setThreads(session, newTids.data(), newTids.size());
EXPECT_EQ(0, result);
+
+ testing::Mock::VerifyAndClearExpectations(mMockIHintManager);
+ std::vector<int32_t> invalidTids;
+ auto status = Status::fromExceptionCode(binder::Status::Exception::EX_SECURITY);
+ invalidTids.push_back(4);
+ invalidTids.push_back(6);
+ EXPECT_CALL(*mMockIHintManager, setHintSessionThreads(_, Eq(invalidTids)))
+ .Times(Exactly(1))
+ .WillOnce(Return(status));
+ result = APerformanceHint_setThreads(session, invalidTids.data(), invalidTids.size());
+ EXPECT_EQ(EPERM, result);
+}
+
+TEST_F(PerformanceHintTest, SetPowerEfficient) {
+ APerformanceHintManager* manager = createManager();
+
+ std::vector<int32_t> tids;
+ tids.push_back(1);
+ tids.push_back(2);
+ int64_t targetDuration = 56789L;
+
+ StrictMock<MockIHintSession>* iSession = new StrictMock<MockIHintSession>();
+ sp<IHintSession> session_sp(iSession);
+
+ EXPECT_CALL(*mMockIHintManager, createHintSession(_, Eq(tids), Eq(targetDuration), _))
+ .Times(Exactly(1))
+ .WillRepeatedly(DoAll(SetArgPointee<3>(std::move(session_sp)), Return(Status())));
+
+ APerformanceHintSession* session =
+ APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
+ ASSERT_TRUE(session);
+
+ EXPECT_CALL(*iSession, setMode(_, Eq(true))).Times(Exactly(1));
+ int result = APerformanceHint_setPreferPowerEfficiency(session, true);
+ EXPECT_EQ(0, result);
+
+ EXPECT_CALL(*iSession, setMode(_, Eq(false))).Times(Exactly(1));
+ result = APerformanceHint_setPreferPowerEfficiency(session, false);
+ EXPECT_EQ(0, result);
}
+
+TEST_F(PerformanceHintTest, CreateZeroTargetDurationSession) {
+ APerformanceHintManager* manager = createManager();
+
+ std::vector<int32_t> tids;
+ tids.push_back(1);
+ tids.push_back(2);
+ int64_t targetDuration = 0;
+
+ StrictMock<MockIHintSession>* iSession = new StrictMock<MockIHintSession>();
+ sp<IHintSession> session_sp(iSession);
+
+ EXPECT_CALL(*mMockIHintManager, createHintSession(_, Eq(tids), Eq(targetDuration), _))
+ .Times(Exactly(1))
+ .WillRepeatedly(DoAll(SetArgPointee<3>(std::move(session_sp)), Return(Status())));
+
+ APerformanceHintSession* session =
+ APerformanceHint_createSession(manager, tids.data(), tids.size(), targetDuration);
+ ASSERT_TRUE(session);
+} \ No newline at end of file
diff --git a/native/android/tests/thermal/Android.bp b/native/android/tests/thermal/Android.bp
new file mode 100644
index 000000000000..8540d8327ada
--- /dev/null
+++ b/native/android/tests/thermal/Android.bp
@@ -0,0 +1,65 @@
+// 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.
+
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+cc_test {
+ name: "NativeThermalUnitTestCases",
+
+ multilib: {
+ lib32: {
+ suffix: "32",
+ },
+ lib64: {
+ suffix: "64",
+ },
+ },
+
+ srcs: ["NativeThermalUnitTest.cpp"],
+
+ shared_libs: [
+ "libandroid",
+ "liblog",
+ "libbinder",
+ "libpowermanager",
+ "libutils",
+ ],
+
+ static_libs: [
+ "libbase",
+ "libgmock",
+ "libgtest",
+ ],
+ stl: "c++_shared",
+
+ test_suites: [
+ "device-tests",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ header_libs: [
+ "libandroid_headers_private",
+ ],
+}
diff --git a/native/android/tests/thermal/NativeThermalUnitTest.cpp b/native/android/tests/thermal/NativeThermalUnitTest.cpp
new file mode 100644
index 000000000000..6d6861a3026a
--- /dev/null
+++ b/native/android/tests/thermal/NativeThermalUnitTest.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "NativeThermalUnitTest"
+
+#include <android/os/IThermalService.h>
+#include <android/thermal.h>
+#include <binder/IBinder.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <thermal_private.h>
+
+using android::binder::Status;
+
+using namespace testing;
+using namespace android;
+using namespace android::os;
+
+class MockIThermalService : public IThermalService {
+public:
+ MOCK_METHOD(Status, registerThermalEventListener,
+ (const ::android::sp<::android::os::IThermalEventListener>& listener,
+ bool* _aidl_return),
+ (override));
+ MOCK_METHOD(Status, registerThermalEventListenerWithType,
+ (const ::android::sp<::android::os::IThermalEventListener>& listener, int32_t type,
+ bool* _aidl_return),
+ (override));
+ MOCK_METHOD(Status, unregisterThermalEventListener,
+ (const ::android::sp<::android::os::IThermalEventListener>& listener,
+ bool* _aidl_return),
+ (override));
+ MOCK_METHOD(Status, getCurrentTemperatures,
+ (::std::vector<::android::os::Temperature> * _aidl_return), (override));
+ MOCK_METHOD(Status, getCurrentTemperaturesWithType,
+ (int32_t type, ::std::vector<::android::os::Temperature>* _aidl_return),
+ (override));
+ MOCK_METHOD(Status, registerThermalStatusListener,
+ (const ::android::sp<::android::os::IThermalStatusListener>& listener,
+ bool* _aidl_return),
+ (override));
+ MOCK_METHOD(Status, unregisterThermalStatusListener,
+ (const ::android::sp<::android::os::IThermalStatusListener>& listener,
+ bool* _aidl_return),
+ (override));
+ MOCK_METHOD(Status, getCurrentThermalStatus, (int32_t * _aidl_return), (override));
+ MOCK_METHOD(Status, getCurrentCoolingDevices,
+ (::std::vector<::android::os::CoolingDevice> * _aidl_return), (override));
+ MOCK_METHOD(Status, getCurrentCoolingDevicesWithType,
+ (int32_t type, ::std::vector<::android::os::CoolingDevice>* _aidl_return),
+ (override));
+ MOCK_METHOD(Status, getThermalHeadroom, (int32_t forecastSeconds, float* _aidl_return),
+ (override));
+ MOCK_METHOD(Status, getThermalHeadroomThresholds, (::std::vector<float> * _aidl_return),
+ (override));
+ MOCK_METHOD(IBinder*, onAsBinder, (), (override));
+};
+
+class NativeThermalUnitTest : public Test {
+public:
+ void SetUp() override {
+ mMockIThermalService = new StrictMock<MockIThermalService>();
+ AThermal_setIThermalServiceForTesting(mMockIThermalService);
+ mThermalManager = AThermal_acquireManager();
+ }
+
+ void TearDown() override {
+ AThermal_setIThermalServiceForTesting(nullptr);
+ AThermal_releaseManager(mThermalManager);
+ }
+
+ StrictMock<MockIThermalService>* mMockIThermalService = nullptr;
+ AThermalManager* mThermalManager = nullptr;
+};
+
+static void checkThermalHeadroomThresholds(const std::vector<float>& expected,
+ const AThermalHeadroomThreshold* thresholds,
+ size_t size) {
+ if (thresholds == nullptr) {
+ FAIL() << "Unexpected null thresholds pointer";
+ }
+ for (int i = 0; i < (int)size; i++) {
+ auto t = thresholds[i];
+ ASSERT_EQ(i, t.thermalStatus) << "threshold " << i << " should have status " << i;
+ ASSERT_EQ(expected[i], t.headroom)
+ << "threshold " << i << " should have headroom " << expected[i];
+ }
+}
+
+TEST_F(NativeThermalUnitTest, TestGetThermalHeadroomThresholds) {
+ std::vector<float> expected = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ EXPECT_CALL(*mMockIThermalService, getThermalHeadroomThresholds(_))
+ .Times(Exactly(1))
+ .WillRepeatedly(DoAll(SetArgPointee<0>(expected), Return(Status())));
+ const AThermalHeadroomThreshold* thresholds1 = nullptr;
+ size_t size1;
+ ASSERT_EQ(OK, AThermal_getThermalHeadroomThresholds(mThermalManager, &thresholds1, &size1));
+ checkThermalHeadroomThresholds(expected, thresholds1, size1);
+ // following calls should be cached
+ EXPECT_CALL(*mMockIThermalService, getThermalHeadroomThresholds(_)).Times(0);
+
+ const AThermalHeadroomThreshold* thresholds2 = nullptr;
+ size_t size2;
+ ASSERT_EQ(OK, AThermal_getThermalHeadroomThresholds(mThermalManager, &thresholds2, &size2));
+ checkThermalHeadroomThresholds(expected, thresholds2, size2);
+}
+
+TEST_F(NativeThermalUnitTest, TestGetThermalHeadroomThresholdsFailedWithServerError) {
+ const AThermalHeadroomThreshold* thresholds = nullptr;
+ size_t size;
+ EXPECT_CALL(*mMockIThermalService, getThermalHeadroomThresholds(_))
+ .Times(Exactly(1))
+ .WillOnce(Return(
+ Status::fromExceptionCode(binder::Status::Exception::EX_ILLEGAL_ARGUMENT)));
+ ASSERT_EQ(EPIPE, AThermal_getThermalHeadroomThresholds(mThermalManager, &thresholds, &size));
+ ASSERT_EQ(nullptr, thresholds);
+}
+
+TEST_F(NativeThermalUnitTest, TestGetThermalHeadroomThresholdsFailedWithFeatureDisabled) {
+ const AThermalHeadroomThreshold* thresholds = nullptr;
+ size_t size;
+ EXPECT_CALL(*mMockIThermalService, getThermalHeadroomThresholds(_))
+ .Times(Exactly(1))
+ .WillOnce(Return(Status::fromExceptionCode(
+ binder::Status::Exception::EX_UNSUPPORTED_OPERATION)));
+ ASSERT_EQ(ENOSYS, AThermal_getThermalHeadroomThresholds(mThermalManager, &thresholds, &size));
+ ASSERT_EQ(nullptr, thresholds);
+}
+
+TEST_F(NativeThermalUnitTest, TestGetThermalHeadroomThresholdsFailedWithNullPtr) {
+ const AThermalHeadroomThreshold* thresholds = nullptr;
+ size_t size;
+ size_t* nullSize = nullptr;
+ ASSERT_EQ(EINVAL,
+ AThermal_getThermalHeadroomThresholds(mThermalManager, &thresholds, nullSize));
+ ASSERT_EQ(nullptr, thresholds);
+ ASSERT_EQ(EINVAL, AThermal_getThermalHeadroomThresholds(mThermalManager, nullptr, &size));
+}
+
+TEST_F(NativeThermalUnitTest, TestGetThermalHeadroomThresholdsFailedWithNonEmptyPtr) {
+ const AThermalHeadroomThreshold* initialized = new AThermalHeadroomThreshold[1];
+ size_t size;
+ ASSERT_EQ(EINVAL, AThermal_getThermalHeadroomThresholds(mThermalManager, &initialized, &size));
+ delete[] initialized;
+}
diff --git a/native/android/tests/thermal/OWNERS b/native/android/tests/thermal/OWNERS
new file mode 100644
index 000000000000..e3bbee92057d
--- /dev/null
+++ b/native/android/tests/thermal/OWNERS
@@ -0,0 +1 @@
+include /ADPF_OWNERS
diff --git a/native/android/thermal.cpp b/native/android/thermal.cpp
index 1f6ef4755aff..b43f2f16a7cb 100644
--- a/native/android/thermal.cpp
+++ b/native/android/thermal.cpp
@@ -16,27 +16,32 @@
#define LOG_TAG "thermal"
-#include <cerrno>
-#include <thread>
-#include <limits>
-
-#include <android/thermal.h>
+#include <android-base/thread_annotations.h>
#include <android/os/BnThermalStatusListener.h>
#include <android/os/IThermalService.h>
+#include <android/thermal.h>
#include <binder/IServiceManager.h>
+#include <thermal_private.h>
#include <utils/Log.h>
+#include <cerrno>
+#include <limits>
+#include <thread>
+
using android::sp;
using namespace android;
using namespace android::os;
struct ThermalServiceListener : public BnThermalStatusListener {
- public:
- virtual binder::Status onStatusChange(int32_t status) override;
- ThermalServiceListener(AThermalManager *manager) {mMgr = manager;}
- private:
- AThermalManager *mMgr;
+public:
+ virtual binder::Status onStatusChange(int32_t status) override;
+ ThermalServiceListener(AThermalManager *manager) {
+ mMgr = manager;
+ }
+
+private:
+ AThermalManager *mMgr;
};
struct ListenerCallback {
@@ -44,22 +49,29 @@ struct ListenerCallback {
void* data;
};
+static IThermalService *gIThermalServiceForTesting = nullptr;
+
struct AThermalManager {
- public:
- static AThermalManager* createAThermalManager();
- AThermalManager() = delete;
- ~AThermalManager();
- status_t notifyStateChange(int32_t status);
- status_t getCurrentThermalStatus(int32_t *status);
- status_t addListener(AThermal_StatusCallback, void *data);
- status_t removeListener(AThermal_StatusCallback, void *data);
- status_t getThermalHeadroom(int32_t forecastSeconds, float *result);
- private:
- AThermalManager(sp<IThermalService> service);
- sp<IThermalService> mThermalSvc;
- sp<ThermalServiceListener> mServiceListener;
- std::vector<ListenerCallback> mListeners;
- std::mutex mMutex;
+public:
+ static AThermalManager *createAThermalManager();
+ AThermalManager() = delete;
+ ~AThermalManager();
+ status_t notifyStateChange(int32_t status);
+ status_t getCurrentThermalStatus(int32_t *status);
+ status_t addListener(AThermal_StatusCallback, void *data);
+ status_t removeListener(AThermal_StatusCallback, void *data);
+ status_t getThermalHeadroom(int32_t forecastSeconds, float *result);
+ status_t getThermalHeadroomThresholds(const AThermalHeadroomThreshold **, size_t *size);
+
+private:
+ AThermalManager(sp<IThermalService> service);
+ sp<IThermalService> mThermalSvc;
+ std::mutex mListenerMutex;
+ sp<ThermalServiceListener> mServiceListener GUARDED_BY(mListenerMutex);
+ std::vector<ListenerCallback> mListeners GUARDED_BY(mListenerMutex);
+ std::mutex mThresholdsMutex;
+ const AThermalHeadroomThreshold *mThresholds = nullptr; // GUARDED_BY(mThresholdsMutex)
+ size_t mThresholdsCount GUARDED_BY(mThresholdsMutex);
};
binder::Status ThermalServiceListener::onStatusChange(int32_t status) {
@@ -70,6 +82,9 @@ binder::Status ThermalServiceListener::onStatusChange(int32_t status) {
}
AThermalManager* AThermalManager::createAThermalManager() {
+ if (gIThermalServiceForTesting) {
+ return new AThermalManager(gIThermalServiceForTesting);
+ }
sp<IBinder> binder =
defaultServiceManager()->checkService(String16("thermalservice"));
@@ -81,12 +96,10 @@ AThermalManager* AThermalManager::createAThermalManager() {
}
AThermalManager::AThermalManager(sp<IThermalService> service)
- : mThermalSvc(service),
- mServiceListener(nullptr) {
-}
+ : mThermalSvc(std::move(service)), mServiceListener(nullptr) {}
AThermalManager::~AThermalManager() {
- std::unique_lock<std::mutex> lock(mMutex);
+ std::unique_lock<std::mutex> listenerLock(mListenerMutex);
mListeners.clear();
if (mServiceListener != nullptr) {
@@ -94,10 +107,13 @@ AThermalManager::~AThermalManager() {
mThermalSvc->unregisterThermalStatusListener(mServiceListener, &success);
mServiceListener = nullptr;
}
+ listenerLock.unlock();
+ std::unique_lock<std::mutex> lock(mThresholdsMutex);
+ delete[] mThresholds;
}
status_t AThermalManager::notifyStateChange(int32_t status) {
- std::unique_lock<std::mutex> lock(mMutex);
+ std::unique_lock<std::mutex> lock(mListenerMutex);
AThermalStatus thermalStatus = static_cast<AThermalStatus>(status);
for (auto listener : mListeners) {
@@ -107,7 +123,7 @@ status_t AThermalManager::notifyStateChange(int32_t status) {
}
status_t AThermalManager::addListener(AThermal_StatusCallback callback, void *data) {
- std::unique_lock<std::mutex> lock(mMutex);
+ std::unique_lock<std::mutex> lock(mListenerMutex);
if (callback == nullptr) {
// Callback can not be nullptr
@@ -141,7 +157,7 @@ status_t AThermalManager::addListener(AThermal_StatusCallback callback, void *da
}
status_t AThermalManager::removeListener(AThermal_StatusCallback callback, void *data) {
- std::unique_lock<std::mutex> lock(mMutex);
+ std::unique_lock<std::mutex> lock(mListenerMutex);
auto it = std::remove_if(mListeners.begin(),
mListeners.end(),
@@ -198,6 +214,32 @@ status_t AThermalManager::getThermalHeadroom(int32_t forecastSeconds, float *res
return OK;
}
+status_t AThermalManager::getThermalHeadroomThresholds(const AThermalHeadroomThreshold **result,
+ size_t *size) {
+ std::unique_lock<std::mutex> lock(mThresholdsMutex);
+ if (mThresholds == nullptr) {
+ auto thresholds = std::make_unique<std::vector<float>>();
+ binder::Status ret = mThermalSvc->getThermalHeadroomThresholds(thresholds.get());
+ if (!ret.isOk()) {
+ if (ret.exceptionCode() == binder::Status::EX_UNSUPPORTED_OPERATION) {
+ // feature is not enabled
+ return ENOSYS;
+ }
+ return EPIPE;
+ }
+ mThresholdsCount = thresholds->size();
+ auto t = new AThermalHeadroomThreshold[mThresholdsCount];
+ for (int i = 0; i < (int)mThresholdsCount; i++) {
+ t[i].headroom = (*thresholds)[i];
+ t[i].thermalStatus = static_cast<AThermalStatus>(i);
+ }
+ mThresholds = t;
+ }
+ *size = mThresholdsCount;
+ *result = mThresholds;
+ return OK;
+}
+
/**
* Acquire an instance of the thermal manager. This must be freed using
* {@link AThermal_releaseManager}.
@@ -291,14 +333,24 @@ int AThermal_unregisterThermalStatusListener(AThermalManager *manager,
* threshold. Returns NaN if the device does not support this functionality or if
* this function is called significantly faster than once per second.
*/
-float AThermal_getThermalHeadroom(AThermalManager *manager,
- int forecastSeconds) {
+float AThermal_getThermalHeadroom(AThermalManager *manager, int forecastSeconds) {
float result = 0.0f;
status_t ret = manager->getThermalHeadroom(forecastSeconds, &result);
-
if (ret != OK) {
result = std::numeric_limits<float>::quiet_NaN();
}
-
return result;
}
+
+int AThermal_getThermalHeadroomThresholds(AThermalManager *manager,
+ const AThermalHeadroomThreshold **outThresholds,
+ size_t *size) {
+ if (outThresholds == nullptr || *outThresholds != nullptr || size == nullptr) {
+ return EINVAL;
+ }
+ return manager->getThermalHeadroomThresholds(outThresholds, size);
+}
+
+void AThermal_setIThermalServiceForTesting(void *iThermalService) {
+ gIThermalServiceForTesting = static_cast<IThermalService *>(iThermalService);
+}
diff --git a/native/webview/TEST_MAPPING b/native/webview/TEST_MAPPING
index c1bc6d720ece..07f438329e43 100644
--- a/native/webview/TEST_MAPPING
+++ b/native/webview/TEST_MAPPING
@@ -26,6 +26,7 @@
},
{
"name": "GtsWebViewTestCases",
+ "keywords": ["internal"],
"options": [
{
"exclude-annotation": "android.test.FlakyTest"
@@ -34,6 +35,7 @@
},
{
"name": "GtsWebViewHostTestCases",
+ "keywords": ["internal"],
"options": [
{
"exclude-annotation": "android.test.FlakyTest"