diff options
author | Bill Yi <byi@google.com> | 2018-11-28 18:34:29 -0800 |
---|---|---|
committer | Bill Yi <byi@google.com> | 2018-11-28 18:34:29 -0800 |
commit | b08bf9c567c4c0822e4265d7d8a5f2f2cb27096c (patch) | |
tree | 279444b82a47a8ab709a39b1914c6668e4e3ef15 | |
parent | 48795e7030e44a05b36af9071255a9815157d7be (diff) | |
parent | cd3bf593acf5ccb3bed5efc8eda0bcf866077c31 (diff) | |
download | interfaces-pie-cuttlefish-testing.tar.gz |
Merge pi-qpr1-release PQ1A.181105.017.A1 to pi-platform-releasepie-platform-releasepie-cuttlefish-testing
Change-Id: Ibdbedcf8ab0f1785a718c2e5b773b6b7af05239e
-rw-r--r-- | CleanSpec.mk | 48 | ||||
-rw-r--r-- | current.txt | 3 | ||||
-rw-r--r-- | light/1.0/Android.bp | 13 | ||||
-rw-r--r-- | light/1.0/ILight.hal | 31 | ||||
-rw-r--r-- | light/1.0/default/Android.bp | 39 | ||||
-rw-r--r-- | light/1.0/default/Light.cpp | 175 | ||||
-rw-r--r-- | light/1.0/default/Light.h | 59 | ||||
-rw-r--r-- | light/1.0/default/LightExt.cpp | 76 | ||||
-rw-r--r-- | light/1.0/default/LightExt.h | 68 | ||||
-rw-r--r-- | light/1.0/default/hardware.google.light@1.0-service.rc | 7 | ||||
-rw-r--r-- | light/1.0/default/service.cpp | 55 | ||||
-rw-r--r-- | pixelstats/1.0/IPixelStats.hal | 6 | ||||
-rw-r--r-- | pixelstats/1.0/default/PixelStats.cpp | 25 | ||||
-rw-r--r-- | pixelstats/1.0/default/PixelStats.h | 7 | ||||
-rw-r--r-- | pixelstats/1.0/default/RateLimiter.cpp | 5 | ||||
-rw-r--r-- | pixelstats/1.0/default/RateLimiter.h | 3 | ||||
-rw-r--r-- | pixelstats/1.0/default/RateLimiterTest.cpp | 19 | ||||
-rw-r--r-- | pixelstats/1.0/test_client/Android.bp | 15 | ||||
-rw-r--r-- | pixelstats/1.0/test_client/OWNERS | 2 | ||||
-rw-r--r-- | pixelstats/1.0/test_client/PixelStatsClient.cpp | 140 | ||||
-rw-r--r-- | pixelstats/1.0/test_client/README | 2 |
21 files changed, 777 insertions, 21 deletions
diff --git a/CleanSpec.mk b/CleanSpec.mk new file mode 100644 index 0000000..c0ac8d6 --- /dev/null +++ b/CleanSpec.mk @@ -0,0 +1,48 @@ +# Copyright (C) 2018 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. +# + +# If you don't need to do a full clean build but would like to touch +# a file or delete some intermediate files, add a clean step to the end +# of the list. These steps will only be run once, if they haven't been +# run before. +# +# E.g.: +# $(call add-clean-step, touch -c external/sqlite/sqlite3.h) +# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates) +# +# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with +# files that are missing or have been moved. +# +# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory. +# Use $(OUT_DIR) to refer to the "out" directory. +# +# If you need to re-do something that's already mentioned, just copy +# the command and add it to the bottom of the list. E.g., if a change +# that you made last week required touching a file and a change you +# made today requires touching the same file, just copy the old +# touch step and add it to the end of the list. +# +# ************************************************ +# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST +# ************************************************ + +# For example: +#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates) +#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates) +#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f) +#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*) + +$(call add-clean-step, find $(PRODUCT_OUT) -name "*vendor.google.light@1.0*" | xargs rm -rf) +$(call add-clean-step, find $(PRODUCT_OUT) -name "*hardware.google.light@1.0*" | xargs rm -rf) diff --git a/current.txt b/current.txt index f30a508..1518722 100644 --- a/current.txt +++ b/current.txt @@ -1,5 +1,6 @@ # HALs released in Android P +b5f3bf3382d7bddf9c22a5f132ff265168e68c4e5373db702cb260d8b20f27d8 hardware.google.light@1.0::ILight 18d5a8fc92f66988a917ab8154f03a19ae8c172ed4000962e230d3c54c9f6ac3 hardware.google.media.c2@1.0::types 5efedcb7df51c465bc0363debbddfb6818ce2e9a813920e7ba0353f855a08d34 hardware.google.media.c2@1.0::IComponent b2932a158633c93cff94f3c9b8728f9cb64db8894c9e7b818e5615f7f004b9f1 hardware.google.media.c2@1.0::IComponentInterface @@ -8,4 +9,4 @@ f05fa15eae2f47d54a69ec85d4c4b4cbaa262d34ba936d85a57406ae78876512 hardware.google 822b5ce551c0cebb9f5a454e164638ec18f0613e248c6cd042aed5deb37fdcbf hardware.google.media.c2@1.0::IConfigurable de8c507e59f9563c880ecea1a04d036e281b83109371543afd5421688bfda301 hardware.google.media.c2@1.0::IInputSurface 843fb9aab0dd6b331ce4fcede131531b23242518749cf87dd5a0ad1feab9070d hardware.google.media.c2@1.0::IInputSurfaceConnection -fe0f8bf91c3ce690567ec417a707c0e707806cf54423ae7b7f52275f293c3c4c hardware.google.pixelstats@1.0::IPixelStats +e5711b645af196287d940a9e801ebc4b21bca374d77c8621e9feadbcf9a703f9 hardware.google.pixelstats@1.0::IPixelStats diff --git a/light/1.0/Android.bp b/light/1.0/Android.bp new file mode 100644 index 0000000..560b3d1 --- /dev/null +++ b/light/1.0/Android.bp @@ -0,0 +1,13 @@ +// This file is autogenerated by hidl-gen -Landroidbp. + +hidl_interface { + name: "hardware.google.light@1.0", + root: "hardware.google", + srcs: [ + "ILight.hal", + ], + interfaces: [ + "android.hardware.light@2.0", + "android.hidl.base@1.0", + ], +} diff --git a/light/1.0/ILight.hal b/light/1.0/ILight.hal new file mode 100644 index 0000000..d857a5a --- /dev/null +++ b/light/1.0/ILight.hal @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2018 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 hardware.google.light@1.0; + +import android.hardware.light@2.0::ILight; +import android.hardware.light@2.0::Status; + +interface ILight extends android.hardware.light@2.0::ILight { + + /** + * Set High Brightness Mode state to light. + * + * @param on/off state + * @return status result of applying state transformation. + */ + setHbm(bool state) generates (Status status); +}; diff --git a/light/1.0/default/Android.bp b/light/1.0/default/Android.bp new file mode 100644 index 0000000..1dc781c --- /dev/null +++ b/light/1.0/default/Android.bp @@ -0,0 +1,39 @@ +// +// Copyright (C) 2018 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. +// + +cc_binary { + name: "hardware.google.light@1.0-service", + relative_install_path: "hw", + defaults: ["hidl_defaults"], + init_rc: ["hardware.google.light@1.0-service.rc"], + vendor: true, + srcs: [ + "Light.cpp", + "LightExt.cpp", + "service.cpp", + ], + + shared_libs: [ + "liblog", + "libbase", + "libutils", + "libhardware", + "libhidlbase", + "libhidltransport", + "android.hardware.light@2.0", + "hardware.google.light@1.0", + ], +} diff --git a/light/1.0/default/Light.cpp b/light/1.0/default/Light.cpp new file mode 100644 index 0000000..902b082 --- /dev/null +++ b/light/1.0/default/Light.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2016-2018 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 "light" + +#include <log/log.h> + +#include <stdio.h> + +#include "Light.h" + +namespace android { +namespace hardware { +namespace light { +namespace V2_0 { +namespace implementation { + +static_assert(LIGHT_FLASH_NONE == static_cast<int>(Flash::NONE), + "Flash::NONE must match legacy value."); +static_assert(LIGHT_FLASH_TIMED == static_cast<int>(Flash::TIMED), + "Flash::TIMED must match legacy value."); +static_assert(LIGHT_FLASH_HARDWARE == static_cast<int>(Flash::HARDWARE), + "Flash::HARDWARE must match legacy value."); + +static_assert(BRIGHTNESS_MODE_USER == static_cast<int>(Brightness::USER), + "Brightness::USER must match legacy value."); +static_assert(BRIGHTNESS_MODE_SENSOR == static_cast<int>(Brightness::SENSOR), + "Brightness::SENSOR must match legacy value."); +static_assert(BRIGHTNESS_MODE_LOW_PERSISTENCE == + static_cast<int>(Brightness::LOW_PERSISTENCE), + "Brightness::LOW_PERSISTENCE must match legacy value."); + +Light::Light(std::map<Type, light_device_t*>&& lights) + : mLights(std::move(lights)) {} + +// Methods from ::android::hardware::light::V2_0::ILight follow. +Return<Status> Light::setLight(Type type, const LightState& state) { + auto it = mLights.find(type); + + if (it == mLights.end()) return Status::LIGHT_NOT_SUPPORTED; + + light_device_t* hwLight = it->second; + + light_state_t legacyState{ + .color = state.color, + .flashMode = static_cast<int>(state.flashMode), + .flashOnMS = state.flashOnMs, + .flashOffMS = state.flashOffMs, + .brightnessMode = static_cast<int>(state.brightnessMode), + }; + + int ret = hwLight->set_light(hwLight, &legacyState); + + switch (ret) { + case -ENOSYS: + return Status::BRIGHTNESS_NOT_SUPPORTED; + case 0: + return Status::SUCCESS; + default: + return Status::UNKNOWN; + } +} + +Return<void> Light::getSupportedTypes(getSupportedTypes_cb _hidl_cb) { + std::vector<Type> types(mLights.size()); + + int idx = 0; + for (const auto& pair : mLights) { + types[idx++] = pair.first; + } + + hidl_vec<Type> hidl_types{}; + hidl_types.setToExternal(types.data(), types.size()); + + _hidl_cb(hidl_types); + + return Void(); +} + +static const std::map<Type, const char*> kLogicalLights = { + {Type::BACKLIGHT, LIGHT_ID_BACKLIGHT}, + {Type::KEYBOARD, LIGHT_ID_KEYBOARD}, + {Type::BUTTONS, LIGHT_ID_BUTTONS}, + {Type::BATTERY, LIGHT_ID_BATTERY}, + {Type::NOTIFICATIONS, LIGHT_ID_NOTIFICATIONS}, + {Type::ATTENTION, LIGHT_ID_ATTENTION}, + {Type::BLUETOOTH, LIGHT_ID_BLUETOOTH}, + {Type::WIFI, LIGHT_ID_WIFI}}; + +Return<void> Light::debug(const hidl_handle& handle, + const hidl_vec<hidl_string>& /* options */) { + if (handle == nullptr || handle->numFds < 1) { + ALOGE("debug called with no handle\n"); + return Void(); + } + + int fd = handle->data[0]; + if (fd < 0) { + ALOGE("invalid FD: %d\n", handle->data[0]); + return Void(); + } + + dprintf(fd, "The following lights are registered: "); + for (const auto& pair : mLights) { + const Type type = pair.first; + dprintf(fd, "%s,", kLogicalLights.at(type)); + } + dprintf(fd, ".\n"); + fsync(fd); + return Void(); +} + +light_device_t* getLightDevice(const char* name) { + light_device_t* lightDevice; + const hw_module_t* hwModule = NULL; + + int ret = hw_get_module(LIGHTS_HARDWARE_MODULE_ID, &hwModule); + if (ret == 0) { + ret = hwModule->methods->open( + hwModule, name, reinterpret_cast<hw_device_t**>(&lightDevice)); + if (ret != 0) + ALOGE("light_open %s %s failed: %d", LIGHTS_HARDWARE_MODULE_ID, name, + ret); + } else { + ALOGE("hw_get_module %s %s failed: %d", LIGHTS_HARDWARE_MODULE_ID, name, + ret); + } + + if (ret == 0) { + return lightDevice; + } else { + ALOGE("Light passthrough failed to load legacy HAL."); + return nullptr; + } +} + +ILight* HIDL_FETCH_ILight(const char* /* name */) { + std::map<Type, light_device_t*> lights; + + for (const auto& pair : kLogicalLights) { + Type type = pair.first; + const char* name = pair.second; + + light_device_t* light = getLightDevice(name); + + if (light != nullptr) lights[type] = light; + } + + if (lights.size() == 0) { + // Log information, but still return new Light. + // Some devices may not have any lights. + ALOGI("Could not open any lights."); + } + + return new Light(std::move(lights)); +} + +} // namespace implementation +} // namespace V2_0 +} // namespace light +} // namespace hardware +} // namespace android diff --git a/light/1.0/default/Light.h b/light/1.0/default/Light.h new file mode 100644 index 0000000..9c8e3bc --- /dev/null +++ b/light/1.0/default/Light.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2016-2018 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. + */ +#ifndef ANDROID_HARDWARE_LIGHT_V2_0_LIGHT_H +#define ANDROID_HARDWARE_LIGHT_V2_0_LIGHT_H + +#include <android/hardware/light/2.0/ILight.h> +#include <hardware/hardware.h> +#include <hardware/lights.h> +#include <hidl/MQDescriptor.h> +#include <hidl/Status.h> +#include <map> + +namespace android { +namespace hardware { +namespace light { +namespace V2_0 { +namespace implementation { + +using ::android::hardware::hidl_string; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::light::V2_0::ILight; +using ::android::hardware::light::V2_0::LightState; +using ::android::hardware::light::V2_0::Status; +using ::android::hardware::light::V2_0::Type; + +struct Light : public ILight { + Light(std::map<Type, light_device_t*>&& lights); + + Return<Status> setLight(Type type, const LightState& state) override; + Return<void> getSupportedTypes(getSupportedTypes_cb _hidl_cb) override; + + Return<void> debug(const hidl_handle& handle, + const hidl_vec<hidl_string>& options) override; + + private: + std::map<Type, light_device_t*> mLights; +}; + +} // namespace implementation +} // namespace V2_0 +} // namespace light +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_LIGHT_V2_0_LIGHT_H diff --git a/light/1.0/default/LightExt.cpp b/light/1.0/default/LightExt.cpp new file mode 100644 index 0000000..ee8790c --- /dev/null +++ b/light/1.0/default/LightExt.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2018 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. + */ +#include <android-base/file.h> +#include <hardware/lights.h> +#include <log/log.h> + +#include "LightExt.h" + +namespace hardware { +namespace google { +namespace light { +namespace V1_0 { +namespace implementation { +using ::android::hardware::light::V2_0::Brightness; + +Return<Status> LightExt::applyHBM(bool on) { + if (!mHasHbmNode) return Status::UNKNOWN; + + /* skip if no change */ + if (mRegHBM == mCurHBM) return Status::SUCCESS; + + if (!android::base::WriteStringToFile((on ? "1" : "0"), + kHighBrightnessModeNode)) { + ALOGE("write HBM failed!"); + return Status::UNKNOWN; + } + + mCurHBM = on; + ALOGI("Set HBM to %d", on); + return Status::SUCCESS; +} + +// Methods from ::android::hardware::light::V2_0::ILight follow. +Return<Status> LightExt::setLight(Type type, const LightState& state) { + if (type == Type::BACKLIGHT) { + if (state.brightnessMode == Brightness::LOW_PERSISTENCE) { + applyHBM(false); + mVRMode = true; + } else { + applyHBM(mRegHBM); + mVRMode = false; + } + } + return mLight->setLight(type, state); +} + +// Methods from ::hardware::google::light::V1_0::ILight follow. +Return<Status> LightExt::setHbm(bool on) { + /* save the request state */ + mRegHBM = on; + + if (mVRMode) return Status::UNKNOWN; + + Status status = applyHBM(mRegHBM); + + return status; +} + +} // namespace implementation +} // namespace V1_0 +} // namespace light +} // namespace google +} // namespace hardware diff --git a/light/1.0/default/LightExt.h b/light/1.0/default/LightExt.h new file mode 100644 index 0000000..aca3b2a --- /dev/null +++ b/light/1.0/default/LightExt.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2018 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. + */ +#ifndef HARDWARE_GOOGLE_LIGHT_V1_0_LIGHT_H +#define HARDWARE_GOOGLE_LIGHT_V1_0_LIGHT_H + +#include <hidl/Status.h> +#include <string> + +#include <hidl/MQDescriptor.h> +#include <hardware/google/light/1.0/ILight.h> +#include "Light.h" + +namespace hardware { +namespace google { +namespace light { +namespace V1_0 { +namespace implementation { + +using ::android::hardware::Return; +using ::android::hardware::light::V2_0::LightState; +using ::android::hardware::light::V2_0::Status; +using ::android::hardware::light::V2_0::Type; +using HwILight = ::android::hardware::light::V2_0::ILight; + +constexpr const char kHighBrightnessModeNode[] = + "/sys/class/backlight/panel0-backlight/hbm_mode"; + +struct LightExt : public ::hardware::google::light::V1_0::ILight { + LightExt(HwILight*&& light) : mLight(light) { + mHasHbmNode = !access(kHighBrightnessModeNode, F_OK); + }; + // Methods from ::android::hardware::light::V2_0::ILight follow. + Return<Status> setLight(Type type, const LightState& state) override; + Return<void> getSupportedTypes(getSupportedTypes_cb _hidl_cb) override { + return mLight->getSupportedTypes(_hidl_cb); + } + + // Methods from ::hardware::google::light::V1_0::ILight follow. + Return<Status> setHbm(bool on) override; + + private: + std::unique_ptr<HwILight> mLight; + Return<Status> applyHBM(bool on); + bool mVRMode = 0; + bool mRegHBM = 0; + bool mCurHBM = 0; + bool mHasHbmNode = false; +}; +} // namespace implementation +} // namespace V1_0 +} // namespace light +} // namespace google +} // namespace hardware + +#endif // HARDWARD_GOOGLE_LIGHT_V1_0_LIGHT_H diff --git a/light/1.0/default/hardware.google.light@1.0-service.rc b/light/1.0/default/hardware.google.light@1.0-service.rc new file mode 100644 index 0000000..a30eb5e --- /dev/null +++ b/light/1.0/default/hardware.google.light@1.0-service.rc @@ -0,0 +1,7 @@ +service vendor.light-1-0 /vendor/bin/hw/hardware.google.light@1.0-service + interface hardware.google.light@1.0::ILight default + class hal + user system + group system + # shutting off lights while powering-off + shutdown critical diff --git a/light/1.0/default/service.cpp b/light/1.0/default/service.cpp new file mode 100644 index 0000000..31bf202 --- /dev/null +++ b/light/1.0/default/service.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2018 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 "hardware.google.light@1.0-service" + +#include <hardware/lights.h> +#include <hidl/LegacySupport.h> +#include <hardware/google/light/1.0/ILight.h> +#include "LightExt.h" + +namespace android { +namespace hardware { +namespace light { +namespace V2_0 { +namespace implementation { + +extern ILight* HIDL_FETCH_ILight(const char* /* name */); + +} // namespace implementation +} // namespace V2_0 +} // namespace light +} // namespace hardware +} // namespace android + +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; +using hardware::google::light::V1_0::implementation::LightExt; +using hwLight = hardware::google::light::V1_0::ILight; + +int main() { + configureRpcThreadpool(1, true /*willJoinThreadpool*/); + + android::sp<hwLight> light = new LightExt{ + android::hardware::light::V2_0::implementation::HIDL_FETCH_ILight( + nullptr)}; + auto ret = light->registerAsService(); + if (ret != android::OK) { + ALOGE("open light servie failed, ret=%d", ret); + return 1; + } + joinRpcThreadpool(); + return 1; +} diff --git a/pixelstats/1.0/IPixelStats.hal b/pixelstats/1.0/IPixelStats.hal index 890a552..b4d3704 100644 --- a/pixelstats/1.0/IPixelStats.hal +++ b/pixelstats/1.0/IPixelStats.hal @@ -132,7 +132,11 @@ interface IPixelStats { MAX_RESISTANCE, // Snapshot at max batt resistance over 24hrs. MIN_VOLTAGE, // Snapshot at min batt voltage over 24hrs. MAX_VOLTAGE, // Snapshot at max batt voltage over 24hrs. - MEDIAN_RESISTANCE, // Snapshot at median battery resistance over 24hrs. + MIN_CURRENT, // Snapshot at min batt current over 24hrs. + MAX_CURRENT, // Snapshot at max batt current over 24hrs. + MIN_BATT_LEVEL, // Snapshot at min battery level (SoC) over 24hrs. + MAX_BATT_LEVEL, // Snapshot at max battery level (SoC) over 24hrs. + AVG_RESISTANCE, // Snapshot at average battery resistance over 24hrs. }; /** Parameters for reportBatteryHealthSnapshot. */ struct BatteryHealthSnapshotArgs { diff --git a/pixelstats/1.0/default/PixelStats.cpp b/pixelstats/1.0/default/PixelStats.cpp index 6ce90f7..b5d3d78 100644 --- a/pixelstats/1.0/default/PixelStats.cpp +++ b/pixelstats/1.0/default/PixelStats.cpp @@ -13,7 +13,7 @@ namespace implementation { using namespace android::metricslogger; PixelStats::PixelStats() - :limiter_(kDailyRatelimit) {} + :limiter_(kOverallDailyRatelimit) {} void loggerAddFields(ComplexEventLogger* logger) { logger->Record(); @@ -21,7 +21,6 @@ void loggerAddFields(ComplexEventLogger* logger) { template<typename... Args> void loggerAddFields(ComplexEventLogger* logger, int32_t field, int32_t value, Args... args) { - logger->AddTaggedData(LOGBUILDER_TYPE, TYPE_ACTION); logger->AddTaggedData(field, value); loggerAddFields(logger, args...); } @@ -73,7 +72,7 @@ Return<void> PixelStats::reportUsbAudioDisconnected(int32_t vid, int32_t pid, Return<void> PixelStats::reportSpeakerImpedance(int32_t speakerLocation, int32_t milliOhms) { // Ratelimit to max 2 / 24hrs (expected 1/24hrs) - if (rateLimit(android::metricslogger::ACTION_SPEAKER_IMPEDANCE, 2)) + if (rateLimit(android::metricslogger::ACTION_SPEAKER_IMPEDANCE, 2, false)) return Void(); logIntAction(android::metricslogger::ACTION_SPEAKER_IMPEDANCE, FIELD_SPEAKER_LOCATION, @@ -133,8 +132,8 @@ Return<void> PixelStats::reportHardwareFailed(HardwareType hardwareType, int32_t Return<void> PixelStats::reportPhysicalDropDetected(int32_t confidencePctg, int32_t accelPeak, int32_t freefallDurationMs) { - // Ratelimit to max 10 / 24hrs (expected 0/24hrs) - if (rateLimit(android::metricslogger::ACTION_PHYSICAL_DROP, 10)) + // Ratelimit to max 50 / 24hrs (expected 0/24hrs) + if (rateLimit(android::metricslogger::ACTION_PHYSICAL_DROP, 50)) return Void(); logIntAction(ACTION_PHYSICAL_DROP, FIELD_CONFIDENCE_PERCENT, confidencePctg, @@ -145,7 +144,7 @@ Return<void> PixelStats::reportPhysicalDropDetected(int32_t confidencePctg, int3 Return<void> PixelStats::reportChargeCycles(const hidl_string& buckets) { // Ratelimit to max 2 / 24hrs (expected 1/24hrs) - if (rateLimit(android::metricslogger::ACTION_BATTERY_CHARGE_CYCLES, 2)) + if (rateLimit(android::metricslogger::ACTION_BATTERY_CHARGE_CYCLES, 2, false)) return Void(); LogMultiAction(ACTION_BATTERY_CHARGE_CYCLES, FIELD_BATTERY_CHARGE_CYCLES, buckets); return Void(); @@ -168,8 +167,8 @@ static android::metricslogger::IoOperation toMetricsLoggerIoOperation(IPixelStat } Return<void> PixelStats::reportSlowIo(IoOperation operation, int32_t count) { - // Ratelimit to max 2 per 24hrs - if (rateLimit(android::metricslogger::ACTION_SLOW_IO, 2)) + // Ratelimit to max 8 per 24hrs (each metric once, with overlap per day) + if (rateLimit(android::metricslogger::ACTION_SLOW_IO, 8, false)) return Void(); logIntAction(ACTION_SLOW_IO, FIELD_IO_OPERATION_TYPE, toMetricsLoggerIoOperation(operation), FIELD_IO_OPERATION_COUNT, count); @@ -177,8 +176,8 @@ Return<void> PixelStats::reportSlowIo(IoOperation operation, int32_t count) { } Return<void> PixelStats::reportBatteryHealthSnapshot(const BatteryHealthSnapshotArgs& args) { - // Ratelimit to max 2 per 24hrs - if (rateLimit(android::metricslogger::ACTION_BATTERY_HEALTH, 2)) + // Ratelimit to max 12 per 24hrs + if (rateLimit(android::metricslogger::ACTION_BATTERY_HEALTH, 12, false)) return Void(); logIntAction(ACTION_BATTERY_HEALTH, FIELD_BATTERY_HEALTH_SNAPSHOT_TYPE, (int32_t)args.type, @@ -193,14 +192,14 @@ Return<void> PixelStats::reportBatteryHealthSnapshot(const BatteryHealthSnapshot Return<void> PixelStats::reportBatteryCausedShutdown(int32_t voltageMicroV) { // Ratelimit to max 5 per 24hrs - if (rateLimit(android::metricslogger::ACTION_BATTERY_CAUSED_SHUTDOWN, 5)) + if (rateLimit(android::metricslogger::ACTION_BATTERY_CAUSED_SHUTDOWN, 5, false)) return Void(); logIntAction(ACTION_BATTERY_CAUSED_SHUTDOWN, FIELD_BATTERY_VOLTAGE_UV, voltageMicroV); return Void(); } -bool PixelStats::rateLimit(int action, int limit) { - if (limiter_.RateLimit(action, limit)) { +bool PixelStats::rateLimit(int action, int limit, bool use_overall_limit) { + if (limiter_.RateLimit(action, limit, use_overall_limit)) { ALOGE("Rate limited action %d\n", action); return true; } diff --git a/pixelstats/1.0/default/PixelStats.h b/pixelstats/1.0/default/PixelStats.h index 5a4e625..c0cfe0f 100644 --- a/pixelstats/1.0/default/PixelStats.h +++ b/pixelstats/1.0/default/PixelStats.h @@ -59,10 +59,11 @@ struct PixelStats : public IPixelStats { private: // At most 150 events per day by default. - static constexpr int32_t kDailyRatelimit = 150; + static constexpr int32_t kOverallDailyRatelimit = 150; - // each action provides its own per-limit daily rate limit. - bool rateLimit(int action, int actionLimit); + // Each action provides its own per-limit daily rate limit. + // Some aren't included in the overall daily limit. + bool rateLimit(int action, int limit, bool use_overall_limit = true); RateLimiter limiter_; }; diff --git a/pixelstats/1.0/default/RateLimiter.cpp b/pixelstats/1.0/default/RateLimiter.cpp index e57b15e..42d8f06 100644 --- a/pixelstats/1.0/default/RateLimiter.cpp +++ b/pixelstats/1.0/default/RateLimiter.cpp @@ -36,7 +36,8 @@ void RateLimiter::SetOverallDailyLimit(int32_t limit) { // Returns true if you should rate limit the action reporting, false if not. // limit: the number of times the action can occur within 24hrs. -bool RateLimiter::RateLimit(int32_t action, int32_t limit) { +// use_overall_limit: if true, apply overall_limit for all actions as well as this action's limit. +bool RateLimiter::RateLimit(int32_t action, int32_t limit, bool use_overall_limit) { std::lock_guard<std::mutex> lock(lock_); int64_t nsecsNow = systemTime(SYSTEM_TIME_BOOTTIME); @@ -52,7 +53,7 @@ bool RateLimiter::RateLimit(int32_t action, int32_t limit) { } if (++counts_[action] > limit) return true; - if (overall_limit_ && ++overall_count_ > overall_limit_) return true; + if (use_overall_limit && overall_limit_ && ++overall_count_ > overall_limit_) return true; return false; } diff --git a/pixelstats/1.0/default/RateLimiter.h b/pixelstats/1.0/default/RateLimiter.h index a937bdb..1d3c6ed 100644 --- a/pixelstats/1.0/default/RateLimiter.h +++ b/pixelstats/1.0/default/RateLimiter.h @@ -34,7 +34,8 @@ class RateLimiter { // Returns true if you should rate limit the action reporting, false if not. // limit: the number of times the action can occur within 24hrs. - bool RateLimit(int32_t action, int32_t limit); + // use_overall_limit: if true, also apply an overall_limit_ for all actions. + bool RateLimit(int32_t action, int32_t limit, bool use_overall_limit = true); // Limit for all actions over a 24hr period. 0 disables overall limit. void SetOverallDailyLimit(int32_t limit); diff --git a/pixelstats/1.0/default/RateLimiterTest.cpp b/pixelstats/1.0/default/RateLimiterTest.cpp index a632878..8c34739 100644 --- a/pixelstats/1.0/default/RateLimiterTest.cpp +++ b/pixelstats/1.0/default/RateLimiterTest.cpp @@ -77,4 +77,23 @@ TEST_F(RateLimiterTest, AllActionLimit) { EXPECT_FALSE(limiter.RateLimit(5, 6)); } +TEST_F(RateLimiterTest, NoOverallLimit) { + RateLimiter limiter(2); + + // Log three actions, expect the third to not be + // ratelimited due to the daily overall ratelimit of 2, since it was + // overridden. + EXPECT_FALSE(limiter.RateLimit(1, 2, false)); + EXPECT_FALSE(limiter.RateLimit(2, 2, false)); + EXPECT_FALSE(limiter.RateLimit(3, 2, false)); + + // make sure individual buckets still ratelimit + EXPECT_FALSE(limiter.RateLimit(1, 2, false)); + EXPECT_TRUE(limiter.RateLimit(1, 2, false)); + + // Expect reset after 25hrs have passed + limiter.TurnBackHours(25); + EXPECT_FALSE(limiter.RateLimit(1, 2, false)); +} + } // namespace diff --git a/pixelstats/1.0/test_client/Android.bp b/pixelstats/1.0/test_client/Android.bp new file mode 100644 index 0000000..1362cfa --- /dev/null +++ b/pixelstats/1.0/test_client/Android.bp @@ -0,0 +1,15 @@ +cc_binary { + name: "pixelstats_client", + srcs: [ + "PixelStatsClient.cpp", + ], + shared_libs: [ + "libbase", + "libhidlbase", + "libhidltransport", + "libutils", + "hardware.google.pixelstats@1.0", + ], + static_libs: ["libmetricslogger_static", ], +} + diff --git a/pixelstats/1.0/test_client/OWNERS b/pixelstats/1.0/test_client/OWNERS new file mode 100644 index 0000000..83e5dea --- /dev/null +++ b/pixelstats/1.0/test_client/OWNERS @@ -0,0 +1,2 @@ +achant@google.com +tstrudel@google.com diff --git a/pixelstats/1.0/test_client/PixelStatsClient.cpp b/pixelstats/1.0/test_client/PixelStatsClient.cpp new file mode 100644 index 0000000..483de05 --- /dev/null +++ b/pixelstats/1.0/test_client/PixelStatsClient.cpp @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2018 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. + */ +#include <hardware/google/pixelstats/1.0/IPixelStats.h> + +#include <metricslogger/metrics_logger.h> +#include <utils/StrongPointer.h> + +#include <getopt.h> +#include <iostream> + +using hardware::google::pixelstats::V1_0::IPixelStats; + +void expect_message(int32_t action) { + std::cout << "expect sysui_multi_action: [757," << action << ",\n"; +} + +void show_help() { + std::cout << "Pixelstats HAL client\n"; + std::cout << " arguments:\n"; + std::cout << " -c or --UsbConnectorConnected\n"; + std::cout << " -C or --UsbConnectorDisconnected\n"; + std::cout << " -a or --UsbAudioConnected\n"; + std::cout << " -A or --UsbAudioDisconnected\n"; + std::cout << " -S or --SpeakerImpedance\n"; + std::cout << " -f or --HardwareFailed\n"; + std::cout << " -y or --ChargeCycles\n"; + std::cout << " -n or --BatteryHealthSnapshot\n"; + std::cout << " -i or --SlowIo\n"; + std::cout << " -s or --BatteryCausedShutdown\n"; + std::cout << "\n\n you can use multiple arguments to trigger multiple events.\n"; +} + +int main(int argc, char* argv[]) { + using namespace hardware::google::pixelstats::V1_0; + + android::sp<IPixelStats> client = IPixelStats::tryGetService(); + if (!client) { + std::cerr << "No PixelStats HAL"; + return 1; + } + + static struct option opts[] = { + {"UsbConnectorConnected", no_argument, 0, 'c'}, + {"UsbConnectorDisconnected", no_argument, 0, 'C'}, + {"UsbAudioConnected", no_argument, 0, 'a'}, + {"UsbAudioDisconnected", no_argument, 0, 'A'}, + {"SpeakerImpedance", no_argument, 0, 'S'}, + {"HardwareFailed", no_argument, 0, 'f'}, + {"ChargeCycles", no_argument, 0, 'y'}, + {"BatteryHealthSnapshot", no_argument, 0, 'n'}, + {"SlowIo", no_argument, 0, 'i'}, + {"BatteryCausedShutdown", no_argument, 0, 's'}, + }; + + int c; + int hal_calls = 0; + while ((c = getopt_long(argc, argv, "cCaASfynis", opts, nullptr)) != -1) { + switch (c) { + case 'c': + client->reportUsbConnectorConnected(); + expect_message(android::metricslogger::ACTION_USB_CONNECTOR_CONNECTED); + ++hal_calls; + break; + case 'C': + client->reportUsbConnectorDisconnected(60); + expect_message(android::metricslogger::ACTION_USB_CONNECTOR_DISCONNECTED); + ++hal_calls; + break; + case 'a': + client->reportUsbAudioConnected(0x5555, 0x1212); + expect_message(android::metricslogger::ACTION_USB_AUDIO_CONNECTED); + ++hal_calls; + break; + case 'A': + client->reportUsbAudioDisconnected(0x5555, 0x1212, 500); + expect_message(android::metricslogger::ACTION_USB_AUDIO_DISCONNECTED); + ++hal_calls; + break; + case 'S': + client->reportSpeakerImpedance(10, 1234); + expect_message(android::metricslogger::ACTION_SPEAKER_IMPEDANCE); + ++hal_calls; + break; + case 'f': + client->reportHardwareFailed(IPixelStats::HardwareType::UNKNOWN, 5, + IPixelStats::HardwareErrorCode::COMPLETE); + expect_message(android::metricslogger::ACTION_HARDWARE_FAILED); + ++hal_calls; + break; + case 'y': + client->reportChargeCycles("1,2,3,4,5,6,7,8"); + expect_message(android::metricslogger::ACTION_BATTERY_CHARGE_CYCLES); + ++hal_calls; + break; + case 'n': + IPixelStats::BatteryHealthSnapshotArgs args; + args.temperatureDeciC = 3000; + args.voltageMicroV = 1; + args.currentMicroA = 2; + args.openCircuitVoltageMicroV = 3; + args.resistanceMicroOhm = 5; + args.levelPercent = 101; + client->reportBatteryHealthSnapshot(args); + expect_message(android::metricslogger::ACTION_BATTERY_HEALTH); + ++hal_calls; + break; + case 'i': + client->reportSlowIo(IPixelStats::IoOperation::UNKNOWN, 5); + expect_message(android::metricslogger::ACTION_SLOW_IO); + ++hal_calls; + break; + case 's': + client->reportBatteryCausedShutdown(3); + expect_message(android::metricslogger::ACTION_BATTERY_CAUSED_SHUTDOWN); + ++hal_calls; + break; + } + } + + if (hal_calls == 0) { + show_help(); + } else { + std::cout << hal_calls << " HAL methods called.\n"; + std::cout << "try: logcat -b events | grep \"sysui_multi_action: \\\\[757\"\n"; + } + return 0; +} diff --git a/pixelstats/1.0/test_client/README b/pixelstats/1.0/test_client/README new file mode 100644 index 0000000..73c9016 --- /dev/null +++ b/pixelstats/1.0/test_client/README @@ -0,0 +1,2 @@ +This client can be installed on the device to test accesses of the service as +it would be called from other clients. |