diff options
Diffstat (limited to 'cmds')
85 files changed, 1282 insertions, 830 deletions
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java index 84a04e5ad6e3..641ae00deda5 100644 --- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java +++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java @@ -71,9 +71,7 @@ public final class Bmgr { return; } - mBmgr = IBackupManager.Stub.asInterface(ServiceManager.getService("backup")); - if (mBmgr == null) { - System.err.println(BMGR_NOT_RUNNING_ERR); + if (!isBmgrActive()) { return; } @@ -150,6 +148,27 @@ public final class Bmgr { showUsage(); } + private boolean isBmgrActive() { + mBmgr = IBackupManager.Stub.asInterface(ServiceManager.getService("backup")); + if (mBmgr == null) { + System.err.println(BMGR_NOT_RUNNING_ERR); + return false; + } + + try { + if (!mBmgr.isBackupServiceActive(UserHandle.USER_SYSTEM)) { + System.err.println(BMGR_NOT_RUNNING_ERR); + return false; + } + } catch (RemoteException e) { + System.err.println(e.toString()); + System.err.println(BMGR_NOT_RUNNING_ERR); + return false; + } + + return true; + } + private String enableToString(boolean enabled) { return enabled ? "enabled" : "disabled"; } @@ -704,34 +723,11 @@ public final class Bmgr { return; } } - - System.out.println("done"); } private void doRestorePackage(String pkg) { - try { - mRestore = mBmgr.beginRestoreSession(pkg, null); - if (mRestore == null) { - System.err.println(BMGR_NOT_RUNNING_ERR); - return; - } - - RestoreObserver observer = new RestoreObserver(); - // TODO implement monitor here - int err = mRestore.restorePackage(pkg, observer, null ); - if (err == 0) { - // Off and running -- wait for the restore to complete - observer.waitForCompletion(); - } else { - System.err.println("Unable to restore package " + pkg); - } - - // And finally shut down the session - mRestore.endRestoreSession(); - } catch (RemoteException e) { - System.err.println(e.toString()); - System.err.println(BMGR_NOT_RUNNING_ERR); - } + System.err.println("The syntax 'restore <package>' is no longer supported, please use "); + System.err.println("'restore <token> <package>'."); } private void doRestoreAll(long token, HashSet<String> filter) { @@ -784,6 +780,8 @@ public final class Bmgr { // once the restore has finished, close down the session and we're done mRestore.endRestoreSession(); + + System.out.println("done"); } catch (RemoteException e) { System.err.println(e.toString()); System.err.println(BMGR_NOT_RUNNING_ERR); @@ -823,7 +821,6 @@ public final class Bmgr { System.err.println(" bmgr transport WHICH|-c WHICH_COMPONENT"); System.err.println(" bmgr restore TOKEN"); System.err.println(" bmgr restore TOKEN PACKAGE..."); - System.err.println(" bmgr restore PACKAGE"); System.err.println(" bmgr run"); System.err.println(" bmgr wipe TRANSPORT PACKAGE"); System.err.println(" bmgr fullbackup PACKAGE..."); @@ -867,10 +864,6 @@ public final class Bmgr { System.err.println("'restore' operation supplying only a token, but applies a filter to the"); System.err.println("set of applications to be restored."); System.err.println(""); - System.err.println("The 'restore' command when given just a package name intiates a restore of"); - System.err.println("just that one package according to the restore set selection algorithm"); - System.err.println("used by the RestoreSession.restorePackage() method."); - System.err.println(""); System.err.println("The 'run' command causes any scheduled backup operation to be initiated"); System.err.println("immediately, without the usual waiting period for batching together"); System.err.println("data changes."); diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk index e5d35b3b8a0e..6943dab0acbe 100644 --- a/cmds/bootanimation/Android.mk +++ b/cmds/bootanimation/Android.mk @@ -27,7 +27,12 @@ ifeq ($(PRODUCT_IOT),true) LOCAL_SHARED_LIBRARIES += \ libandroidthings \ + libandroidthings_protos \ libchrome \ + libprotobuf-cpp-lite \ + +LOCAL_STATIC_LIBRARIES += \ + libjsoncpp LOCAL_SRC_FILES += \ iot/iotbootanimation_main.cpp \ @@ -94,3 +99,5 @@ LOCAL_32_BIT_ONLY := true endif include ${BUILD_SHARED_LIBRARY} + +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h index 56e131523bcb..dffbfde649e0 100644 --- a/cmds/bootanimation/BootAnimation.h +++ b/cmds/bootanimation/BootAnimation.h @@ -22,6 +22,7 @@ #include <androidfw/AssetManager.h> #include <utils/Thread.h> +#include <binder/IBinder.h> #include <EGL/egl.h> #include <GLES/gl.h> diff --git a/cmds/bootanimation/BootAnimationUtil.cpp b/cmds/bootanimation/BootAnimationUtil.cpp index 7718daf61d81..1e417e938359 100644 --- a/cmds/bootanimation/BootAnimationUtil.cpp +++ b/cmds/bootanimation/BootAnimationUtil.cpp @@ -16,14 +16,30 @@ #include "BootAnimationUtil.h" +#include <vector> #include <inttypes.h> #include <binder/IServiceManager.h> #include <cutils/properties.h> #include <utils/Log.h> #include <utils/SystemClock.h> +#include <android-base/properties.h> namespace android { +namespace { + +static constexpr char PLAY_SOUND_PROP_NAME[] = "persist.sys.bootanim.play_sound"; +static constexpr char BOOT_COMPLETED_PROP_NAME[] = "sys.boot_completed"; +static constexpr char POWER_CTL_PROP_NAME[] = "sys.powerctl"; +static constexpr char BOOTREASON_PROP_NAME[] = "ro.boot.bootreason"; +static const std::vector<std::string> PLAY_SOUND_BOOTREASON_BLACKLIST { + "kernel_panic", + "Panic", + "Watchdog", +}; + +} // namespace + bool bootAnimationDisabled() { char value[PROPERTY_VALUE_MAX]; @@ -58,4 +74,31 @@ void waitForSurfaceFlinger() { } } +bool playSoundsAllowed() { + // Only play sounds for system boots, not runtime restarts. + if (android::base::GetBoolProperty(BOOT_COMPLETED_PROP_NAME, false)) { + return false; + } + // no audio while shutting down + if (!android::base::GetProperty(POWER_CTL_PROP_NAME, "").empty()) { + return false; + } + // Read the system property to see if we should play the sound. + // If it's not present, default to allowed. + if (!property_get_bool(PLAY_SOUND_PROP_NAME, 1)) { + return false; + } + + // Don't play sounds if this is a reboot due to an error. + char bootreason[PROPERTY_VALUE_MAX]; + if (property_get(BOOTREASON_PROP_NAME, bootreason, nullptr) > 0) { + for (const auto& str : PLAY_SOUND_BOOTREASON_BLACKLIST) { + if (strcasecmp(str.c_str(), bootreason) == 0) { + return false; + } + } + } + return true; +} + } // namespace android diff --git a/cmds/bootanimation/BootAnimationUtil.h b/cmds/bootanimation/BootAnimationUtil.h index 60987cd1ccd1..1e1140a51763 100644 --- a/cmds/bootanimation/BootAnimationUtil.h +++ b/cmds/bootanimation/BootAnimationUtil.h @@ -14,6 +14,9 @@ * limitations under the License. */ +#ifndef ANDROID_BOOTANIMATION_UTIL_H +#define ANDROID_BOOTANIMATION_UTIL_H + namespace android { // Returns true if boot animation is disabled. @@ -22,4 +25,8 @@ bool bootAnimationDisabled(); // Waits until the surface flinger is up. void waitForSurfaceFlinger(); +// Returns whether sounds should be played during current boot. +bool playSoundsAllowed(); } // namespace android + +#endif // ANDROID_BOOTANIMATION_UTIL_H diff --git a/cmds/bootanimation/audioplay.cpp b/cmds/bootanimation/audioplay.cpp index c546072e733a..874aab08862e 100644 --- a/cmds/bootanimation/audioplay.cpp +++ b/cmds/bootanimation/audioplay.cpp @@ -17,22 +17,27 @@ // cribbed from samples/native-audio -#include "audioplay.h" - #define CHATTY ALOGD #define LOG_TAG "audioplay" +#include "audioplay.h" + #include <string.h> #include <utils/Log.h> +#include <utils/threads.h> // for native audio #include <SLES/OpenSLES.h> #include <SLES/OpenSLES_Android.h> +#include "BootAnimationUtil.h" + namespace audioplay { namespace { +using namespace android; + // engine interfaces static SLObjectItf engineObject = NULL; static SLEngineItf engineEngine; @@ -305,6 +310,74 @@ bool parseClipBuf(const uint8_t* clipBuf, int clipBufSize, const ChunkFormat** o return true; } +class InitAudioThread : public Thread { +public: + InitAudioThread(uint8_t* exampleAudioData, int exampleAudioLength) + : Thread(false), + mExampleAudioData(exampleAudioData), + mExampleAudioLength(exampleAudioLength) {} +private: + virtual bool threadLoop() { + audioplay::create(mExampleAudioData, mExampleAudioLength); + // Exit immediately + return false; + } + + uint8_t* mExampleAudioData; + int mExampleAudioLength; +}; + +// Typedef to aid readability. +typedef android::BootAnimation::Animation Animation; + +class AudioAnimationCallbacks : public android::BootAnimation::Callbacks { +public: + void init(const Vector<Animation::Part>& parts) override { + const Animation::Part* partWithAudio = nullptr; + for (const Animation::Part& part : parts) { + if (part.audioData != nullptr) { + partWithAudio = ∂ + break; + } + } + + if (partWithAudio == nullptr) { + return; + } + + ALOGD("found audio.wav, creating playback engine"); + // The audioData is used to initialize the audio system. Different data + // can be played later for other parts BUT the assumption is that they + // will all be the same format and only the format of this audioData + // will work correctly. + initAudioThread = new InitAudioThread(partWithAudio->audioData, + partWithAudio->audioLength); + initAudioThread->run("BootAnimation::InitAudioThread", PRIORITY_NORMAL); + }; + + void playPart(int partNumber, const Animation::Part& part, int playNumber) override { + // only play audio file the first time we animate the part + if (playNumber == 0 && part.audioData && playSoundsAllowed()) { + ALOGD("playing clip for part%d, size=%d", + partNumber, part.audioLength); + // Block until the audio engine is finished initializing. + if (initAudioThread != nullptr) { + initAudioThread->join(); + } + audioplay::playClip(part.audioData, part.audioLength); + } + }; + + void shutdown() override { + // we've finally played everything we're going to play + audioplay::setPlaying(false); + audioplay::destroy(); + }; + +private: + sp<InitAudioThread> initAudioThread = nullptr; +}; + } // namespace bool create(const uint8_t* exampleClipBuf, int exampleClipBufSize) { @@ -397,4 +470,8 @@ void destroy() { } } +sp<BootAnimation::Callbacks> createAnimationCallbacks() { + return new AudioAnimationCallbacks(); +} + } // namespace audioplay diff --git a/cmds/bootanimation/audioplay.h b/cmds/bootanimation/audioplay.h index 0e5705af0ad0..4704a702d50b 100644 --- a/cmds/bootanimation/audioplay.h +++ b/cmds/bootanimation/audioplay.h @@ -20,6 +20,8 @@ #include <string.h> +#include "BootAnimation.h" + namespace audioplay { // Initializes the engine with an example of the type of WAV clip to play. @@ -32,6 +34,9 @@ bool playClip(const uint8_t* buf, int size); void setPlaying(bool isPlaying); void destroy(); +// Generates callbacks to integrate the audioplay system with the BootAnimation. +android::sp<android::BootAnimation::Callbacks> createAnimationCallbacks(); + } #endif // AUDIOPLAY_H_ diff --git a/cmds/bootanimation/bootanimation_main.cpp b/cmds/bootanimation/bootanimation_main.cpp index 8501982d071c..a52a5e92a840 100644 --- a/cmds/bootanimation/bootanimation_main.cpp +++ b/cmds/bootanimation/bootanimation_main.cpp @@ -26,8 +26,6 @@ #include <sys/resource.h> #include <utils/Log.h> #include <utils/SystemClock.h> -#include <utils/threads.h> -#include <android-base/properties.h> #include "BootAnimation.h" #include "BootAnimationUtil.h" @@ -35,113 +33,6 @@ using namespace android; -// --------------------------------------------------------------------------- - -namespace { - -// Create a typedef for readability. -typedef android::BootAnimation::Animation Animation; - -static const char PLAY_SOUND_PROP_NAME[] = "persist.sys.bootanim.play_sound"; -static const char BOOT_COMPLETED_PROP_NAME[] = "sys.boot_completed"; -static const char POWER_CTL_PROP_NAME[] = "sys.powerctl"; -static const char BOOTREASON_PROP_NAME[] = "ro.boot.bootreason"; -static const std::vector<std::string> PLAY_SOUND_BOOTREASON_BLACKLIST { - "kernel_panic", - "Panic", - "Watchdog", -}; - -class InitAudioThread : public Thread { -public: - InitAudioThread(uint8_t* exampleAudioData, int exampleAudioLength) - : Thread(false), - mExampleAudioData(exampleAudioData), - mExampleAudioLength(exampleAudioLength) {} -private: - virtual bool threadLoop() { - audioplay::create(mExampleAudioData, mExampleAudioLength); - // Exit immediately - return false; - } - - uint8_t* mExampleAudioData; - int mExampleAudioLength; -}; - -bool playSoundsAllowed() { - // Only play sounds for system boots, not runtime restarts. - if (android::base::GetBoolProperty(BOOT_COMPLETED_PROP_NAME, false)) { - return false; - } - // no audio while shutting down - if (!android::base::GetProperty(POWER_CTL_PROP_NAME, "").empty()) { - return false; - } - // Read the system property to see if we should play the sound. - // If it's not present, default to allowed. - if (!property_get_bool(PLAY_SOUND_PROP_NAME, 1)) { - return false; - } - - // Don't play sounds if this is a reboot due to an error. - char bootreason[PROPERTY_VALUE_MAX]; - if (property_get(BOOTREASON_PROP_NAME, bootreason, nullptr) > 0) { - for (const auto& str : PLAY_SOUND_BOOTREASON_BLACKLIST) { - if (strcasecmp(str.c_str(), bootreason) == 0) { - return false; - } - } - } - return true; -} - -class AudioAnimationCallbacks : public android::BootAnimation::Callbacks { -public: - void init(const Vector<Animation::Part>& parts) override { - const Animation::Part* partWithAudio = nullptr; - for (const Animation::Part& part : parts) { - if (part.audioData != nullptr) { - partWithAudio = ∂ - } - } - - if (partWithAudio == nullptr) { - return; - } - - ALOGD("found audio.wav, creating playback engine"); - initAudioThread = new InitAudioThread(partWithAudio->audioData, - partWithAudio->audioLength); - initAudioThread->run("BootAnimation::InitAudioThread", PRIORITY_NORMAL); - }; - - void playPart(int partNumber, const Animation::Part& part, int playNumber) override { - // only play audio file the first time we animate the part - if (playNumber == 0 && part.audioData && playSoundsAllowed()) { - ALOGD("playing clip for part%d, size=%d", - partNumber, part.audioLength); - // Block until the audio engine is finished initializing. - if (initAudioThread != nullptr) { - initAudioThread->join(); - } - audioplay::playClip(part.audioData, part.audioLength); - } - }; - - void shutdown() override { - // we've finally played everything we're going to play - audioplay::setPlaying(false); - audioplay::destroy(); - }; - -private: - sp<InitAudioThread> initAudioThread = nullptr; -}; - -} // namespace - - int main() { setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY); @@ -156,7 +47,7 @@ int main() waitForSurfaceFlinger(); // create the boot animation object - sp<BootAnimation> boot = new BootAnimation(new AudioAnimationCallbacks()); + sp<BootAnimation> boot = new BootAnimation(audioplay::createAnimationCallbacks()); ALOGV("Boot animation set up. Joining pool."); IPCThreadState::self()->joinThreadPool(); diff --git a/cmds/bootanimation/iot/Android.mk b/cmds/bootanimation/iot/Android.mk new file mode 100644 index 000000000000..3d288e4e111b --- /dev/null +++ b/cmds/bootanimation/iot/Android.mk @@ -0,0 +1,43 @@ +# 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. +# + +LOCAL_PATH:= $(call my-dir) + +ifeq ($(PRODUCT_IOT),true) + +# libbootanimation_iot_test +# =========================================================== +include $(CLEAR_VARS) +LOCAL_MODULE := libbootanimation_iot_test +LOCAL_CFLAGS := -Wall -Werror -Wunused -Wunreachable-code + +LOCAL_SHARED_LIBRARIES := \ + libandroidthings \ + libandroidthings_protos \ + libbase \ + libchrome \ + liblog \ + libprotobuf-cpp-lite \ + +LOCAL_STATIC_LIBRARIES += \ + libjsoncpp + +LOCAL_SRC_FILES := \ + BootParameters.cpp \ + BootParameters_test.cpp \ + +include $(BUILD_NATIVE_TEST) + +endif # PRODUCT_IOT diff --git a/cmds/bootanimation/iot/BootAction.cpp b/cmds/bootanimation/iot/BootAction.cpp index fa797444d569..8b55147110bc 100644 --- a/cmds/bootanimation/iot/BootAction.cpp +++ b/cmds/bootanimation/iot/BootAction.cpp @@ -32,7 +32,7 @@ BootAction::~BootAction() { } bool BootAction::init(const std::string& libraryPath, - const std::vector<ABootActionParameter>& parameters) { + const std::unique_ptr<BootParameters>& bootParameters) { APeripheralManagerClient* client = nullptr; ALOGD("Connecting to peripheralmanager"); // Wait for peripheral manager to come up. @@ -77,9 +77,32 @@ bool BootAction::init(const std::string& libraryPath, mLibStartPart = reinterpret_cast<libStartPart>(loaded); } - ALOGD("Entering boot_action_init"); - bool result = mLibInit(parameters.data(), parameters.size()); - ALOGD("Returned from boot_action_init"); + // SilentBoot is considered optional, if it isn't exported by the library + // and the boot is silent, no method is called. + loaded = nullptr; + if (!loadSymbol("boot_action_silent_boot", &loaded) || loaded == nullptr) { + ALOGW("No boot_action_silent_boot found, boot action will not be " + "executed during a silent boot."); + } else { + mLibSilentBoot = reinterpret_cast<libInit>(loaded); + } + + bool result = true; + const auto& parameters = bootParameters->getParameters(); + if (bootParameters->isSilentBoot()) { + if (mLibSilentBoot != nullptr) { + ALOGD("Entering boot_action_silent_boot"); + result = mLibSilentBoot(parameters.data(), parameters.size()); + ALOGD("Returned from boot_action_silent_boot"); + } else { + ALOGW("Skipping missing boot_action_silent_boot"); + } + } else { + ALOGD("Entering boot_action_init"); + result = mLibInit(parameters.data(), parameters.size()); + ALOGD("Returned from boot_action_init"); + } + return result; } @@ -99,7 +122,7 @@ void BootAction::shutdown() { bool BootAction::loadSymbol(const char* symbol, void** loaded) { *loaded = dlsym(mLibHandle, symbol); - if (loaded == nullptr) { + if (*loaded == nullptr) { ALOGE("Unable to load symbol : %s :: %s", symbol, dlerror()); return false; } diff --git a/cmds/bootanimation/iot/BootAction.h b/cmds/bootanimation/iot/BootAction.h index 5e2495fe6c51..7119c35db0f9 100644 --- a/cmds/bootanimation/iot/BootAction.h +++ b/cmds/bootanimation/iot/BootAction.h @@ -20,6 +20,8 @@ #include <string> #include <vector> +#include "BootParameters.h" + #include <boot_action/boot_action.h> // libandroidthings native API. #include <utils/RefBase.h> @@ -31,7 +33,7 @@ public: // libraryPath is a fully qualified path to the target .so library. bool init(const std::string& libraryPath, - const std::vector<ABootActionParameter>& parameters); + const std::unique_ptr<BootParameters>& bootParameters); // The animation is going to start playing partNumber for the playCount'th // time, update the action as needed. @@ -45,7 +47,7 @@ public: private: typedef bool (*libInit)(const ABootActionParameter* parameters, - size_t num_parameters); + size_t numParameters); typedef void (*libStartPart)(int partNumber, int playNumber); typedef void (*libShutdown)(); @@ -55,6 +57,9 @@ private: libInit mLibInit = nullptr; libStartPart mLibStartPart = nullptr; libShutdown mLibShutdown = nullptr; + + // Called only if the boot is silent. + libInit mLibSilentBoot = nullptr; }; } // namespace android diff --git a/cmds/bootanimation/iot/BootParameters.cpp b/cmds/bootanimation/iot/BootParameters.cpp index da6ad0d1f08f..30a9b2895c44 100644 --- a/cmds/bootanimation/iot/BootParameters.cpp +++ b/cmds/bootanimation/iot/BootParameters.cpp @@ -18,45 +18,52 @@ #define LOG_TAG "BootParameters" +#include <errno.h> #include <fcntl.h> -#include <string> - #include <android-base/file.h> -#include <base/json/json_parser.h> -#include <base/json/json_reader.h> -#include <base/json/json_value_converter.h> +#include <json/json.h> #include <utils/Log.h> -using android::base::RemoveFileIfExists; using android::base::ReadFileToString; -using base::JSONReader; -using base::JSONValueConverter; -using base::Value; +using android::base::RemoveFileIfExists; +using android::base::WriteStringToFile; +using Json::ArrayIndex; +using Json::Reader; +using Json::Value; namespace android { namespace { -// Brightness and volume are stored as integer strings in next_boot.json. -// They are divided by this constant to produce the actual float values in -// range [0.0, 1.0]. This constant must match its counterpart in -// DeviceManager. -constexpr const float kFloatScaleFactor = 1000.0f; +// Keys for deprecated parameters. Devices that OTA from N to O and that used +// the hidden BootParameters API will store these in the JSON blob. To support +// the transition from N to O, these keys are mapped to the new parameters. +constexpr const char *kKeyLegacyVolume = "volume"; +constexpr const char *kKeyLegacyAnimationsDisabled = "boot_animation_disabled"; +constexpr const char *kKeyLegacyParamNames = "param_names"; +constexpr const char *kKeyLegacyParamValues = "param_values"; + +constexpr const char *kNextBootFile = "/data/misc/bootanimation/next_boot.proto"; +constexpr const char *kLastBootFile = "/data/misc/bootanimation/last_boot.proto"; -constexpr const char* kNextBootFile = "/data/misc/bootanimation/next_boot.json"; -constexpr const char* kLastBootFile = "/data/misc/bootanimation/last_boot.json"; +constexpr const char *kLegacyNextBootFile = "/data/misc/bootanimation/next_boot.json"; +constexpr const char *kLegacyLastBootFile = "/data/misc/bootanimation/last_boot.json"; -void swapBootConfigs() { - // rename() will fail if next_boot.json doesn't exist, so delete - // last_boot.json manually first. +void removeLegacyFiles() { std::string err; - if (!RemoveFileIfExists(kLastBootFile, &err)) - ALOGE("Unable to delete last boot file: %s", err.c_str()); + if (!RemoveFileIfExists(kLegacyLastBootFile, &err)) { + ALOGW("Unable to delete %s: %s", kLegacyLastBootFile, err.c_str()); + } - if (rename(kNextBootFile, kLastBootFile) && errno != ENOENT) - ALOGE("Unable to swap boot files: %s", strerror(errno)); + err.clear(); + if (!RemoveFileIfExists(kLegacyNextBootFile, &err)) { + ALOGW("Unable to delete %s: %s", kLegacyNextBootFile, err.c_str()); + } +} +void createNextBootFile() { + errno = 0; int fd = open(kNextBootFile, O_CREAT, DEFFILEMODE); if (fd == -1) { ALOGE("Unable to create next boot file: %s", strerror(errno)); @@ -71,54 +78,120 @@ void swapBootConfigs() { } // namespace -BootParameters::SavedBootParameters::SavedBootParameters() - : brightness(-kFloatScaleFactor), volume(-kFloatScaleFactor) {} - -void BootParameters::SavedBootParameters::RegisterJSONConverter( - JSONValueConverter<SavedBootParameters>* converter) { - converter->RegisterIntField("brightness", &SavedBootParameters::brightness); - converter->RegisterIntField("volume", &SavedBootParameters::volume); - converter->RegisterRepeatedString("param_names", - &SavedBootParameters::param_names); - converter->RegisterRepeatedString("param_values", - &SavedBootParameters::param_values); +// Renames the 'next' boot file to the 'last' file and reads its contents. +bool BootParameters::swapAndLoadBootConfigContents(const char *lastBootFile, + const char *nextBootFile, + std::string *contents) { + if (!ReadFileToString(nextBootFile, contents)) { + RemoveFileIfExists(lastBootFile); + return false; + } + + errno = 0; + if (rename(nextBootFile, lastBootFile) && errno != ENOENT) + ALOGE("Unable to swap boot files: %s", strerror(errno)); + + return true; } BootParameters::BootParameters() { - swapBootConfigs(); loadParameters(); } +// Saves the boot parameters state to disk so the framework can read it. +void BootParameters::storeParameters() { + errno = 0; + if (!WriteStringToFile(mProto.SerializeAsString(), kLastBootFile)) { + ALOGE("Failed to write boot parameters to %s: %s", kLastBootFile, strerror(errno)); + } + + // WriteStringToFile sets the file permissions to 0666, but these are not + // honored by the system. + errno = 0; + if (chmod(kLastBootFile, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) { + ALOGE("Failed to set permissions for %s: %s", kLastBootFile, strerror(errno)); + } +} + +// Load the boot parameters from disk, try the old location and format if the +// file does not exist. Note: +// - Parse errors result in defaults being used (a normal boot). +// - Legacy boot parameters default to a silent boot. void BootParameters::loadParameters() { + // Precedence is given to the new file format (.proto). std::string contents; - if (!ReadFileToString(kLastBootFile, &contents)) { - if (errno != ENOENT) - ALOGE("Unable to read from %s: %s", kLastBootFile, strerror(errno)); + if (swapAndLoadBootConfigContents(kLastBootFile, kNextBootFile, &contents)) { + parseBootParameters(contents); + } else if (swapAndLoadBootConfigContents(kLegacyLastBootFile, kLegacyNextBootFile, &contents)) { + parseLegacyBootParameters(contents); + storeParameters(); + removeLegacyFiles(); + } + + createNextBootFile(); +} +void BootParameters::parseBootParameters(const std::string &contents) { + if (!mProto.ParseFromString(contents)) { + ALOGW("Failed to parse parameters from %s", kLastBootFile); return; } - std::unique_ptr<Value> json = JSONReader::Read(contents); - if (json.get() == nullptr) { + loadStateFromProto(); +} + +// Parses the JSON in the proto. +void BootParameters::parseLegacyBootParameters(const std::string &contents) { + Value json; + if (!Reader().parse(contents, json)) { + ALOGW("Failed to parse parameters from %s", kLegacyLastBootFile); return; } - JSONValueConverter<SavedBootParameters> converter; - if (converter.Convert(*(json.get()), &mRawParameters)) { - mBrightness = mRawParameters.brightness / kFloatScaleFactor; - mVolume = mRawParameters.volume / kFloatScaleFactor; - - if (mRawParameters.param_names.size() == mRawParameters.param_values.size()) { - for (size_t i = 0; i < mRawParameters.param_names.size(); i++) { - mParameters.push_back({ - .key = mRawParameters.param_names[i]->c_str(), - .value = mRawParameters.param_values[i]->c_str() - }); + int volume = 0; + bool bootAnimationDisabled = true; + + Value &jsonValue = json[kKeyLegacyVolume]; + if (jsonValue.isIntegral()) { + volume = jsonValue.asInt(); + } + + jsonValue = json[kKeyLegacyAnimationsDisabled]; + if (jsonValue.isIntegral()) { + bootAnimationDisabled = jsonValue.asInt() == 1; + } + + // Assume a silent boot unless all of the following are true - + // 1. The volume is neither 0 nor -1000 (the legacy default value). + // 2. The boot animations are explicitly enabled. + // Note: brightness was never used. + mProto.set_silent_boot((volume == 0) || (volume == -1000) || bootAnimationDisabled); + + Value &keys = json[kKeyLegacyParamNames]; + Value &values = json[kKeyLegacyParamValues]; + if (keys.isArray() && values.isArray() && (keys.size() == values.size())) { + for (ArrayIndex i = 0; i < keys.size(); ++i) { + auto &key = keys[i]; + auto &value = values[i]; + if (key.isString() && value.isString()) { + auto userParameter = mProto.add_user_parameter(); + userParameter->set_key(key.asString()); + userParameter->set_value(value.asString()); } - } else { - ALOGW("Parameter names and values size mismatch"); } } + + loadStateFromProto(); +} + +void BootParameters::loadStateFromProto() { + // A missing key returns a safe, default value. + // Ignore invalid or missing parameters. + mIsSilentBoot = mProto.silent_boot(); + + for (const auto ¶m : mProto.user_parameter()) { + mParameters.push_back({.key = param.key().c_str(), .value = param.value().c_str()}); + } } } // namespace android diff --git a/cmds/bootanimation/iot/BootParameters.h b/cmds/bootanimation/iot/BootParameters.h index c10bd44bc2ca..cbd1ca61cfc3 100644 --- a/cmds/bootanimation/iot/BootParameters.h +++ b/cmds/bootanimation/iot/BootParameters.h @@ -18,10 +18,11 @@ #define _BOOTANIMATION_BOOT_PARAMETERS_H_ #include <list> +#include <string> #include <vector> -#include <base/json/json_value_converter.h> #include <boot_action/boot_action.h> // libandroidthings native API. +#include <boot_parameters.pb.h> namespace android { @@ -32,39 +33,39 @@ public: // to clear the parameters for next boot. BootParameters(); - // Returns true if volume/brightness were explicitly set on reboot. - bool hasVolume() const { return mVolume >= 0; } - bool hasBrightness() const { return mBrightness >= 0; } - - // Returns volume/brightness in [0,1], or -1 if unset. - float getVolume() const { return mVolume; } - float getBrightness() const { return mBrightness; } + // Returns whether or not this is a silent boot. + bool isSilentBoot() const { return mIsSilentBoot; } // Returns the additional boot parameters that were set on reboot. const std::vector<ABootActionParameter>& getParameters() const { return mParameters; } -private: - // Raw boot saved_parameters loaded from .json. - struct SavedBootParameters { - int brightness; - int volume; - std::vector<std::unique_ptr<std::string>> param_names; - std::vector<std::unique_ptr<std::string>> param_values; + // Exposed for testing. Sets the parameters to the serialized proto. + void parseBootParameters(const std::string &contents); + + // For devices that OTA from N to O. + // Exposed for testing. Sets the parameters to the raw JSON. + void parseLegacyBootParameters(const std::string &contents); - SavedBootParameters(); - static void RegisterJSONConverter( - ::base::JSONValueConverter<SavedBootParameters>* converter); - }; + // Exposed for testing. Loads the contents from |nextBootFile| and replaces + // |lastBootFile| with |nextBootFile|. + static bool swapAndLoadBootConfigContents(const char *lastBootFile, const char *nextBootFile, + std::string *contents); + private: void loadParameters(); - float mVolume = -1.f; - float mBrightness = -1.f; + // Replaces the legacy JSON blob with the updated version, allowing the + // framework to read it. + void storeParameters(); + + void loadStateFromProto(); + + bool mIsSilentBoot = false; + std::vector<ABootActionParameter> mParameters; - // ABootActionParameter is just a raw pointer so we need to keep the - // original strings around to avoid losing them. - SavedBootParameters mRawParameters; + // Store the proto because mParameters makes a shallow copy. + android::things::proto::BootParameters mProto; }; } // namespace android diff --git a/cmds/bootanimation/iot/BootParameters_test.cpp b/cmds/bootanimation/iot/BootParameters_test.cpp new file mode 100644 index 000000000000..d55bce6eecc3 --- /dev/null +++ b/cmds/bootanimation/iot/BootParameters_test.cpp @@ -0,0 +1,263 @@ +/* + * 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 "BootParameters.h" + +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include <android-base/file.h> +#include <android-base/test_utils.h> +#include <boot_parameters.pb.h> +#include <gtest/gtest.h> + +namespace android { + +namespace { + +TEST(BootParametersTest, TestNoBootParametersIsNotSilent) { + android::things::proto::BootParameters proto; + + BootParameters bootParameters = BootParameters(); + bootParameters.parseBootParameters(proto.SerializeAsString()); + + ASSERT_FALSE(bootParameters.isSilentBoot()); + ASSERT_EQ(0u, bootParameters.getParameters().size()); +} + +TEST(BootParametersTest, TestParseIsSilent) { + android::things::proto::BootParameters proto; + proto.set_silent_boot(true); + + BootParameters bootParameters = BootParameters(); + bootParameters.parseBootParameters(proto.SerializeAsString()); + + ASSERT_TRUE(bootParameters.isSilentBoot()); +} + +TEST(BootParametersTest, TestParseIsNotSilent) { + android::things::proto::BootParameters proto; + proto.set_silent_boot(false); + + BootParameters bootParameters = BootParameters(); + bootParameters.parseBootParameters(proto.SerializeAsString()); + + ASSERT_FALSE(bootParameters.isSilentBoot()); +} + +TEST(BootParametersTest, TestParseBootParameters) { + android::things::proto::BootParameters proto; + proto.set_silent_boot(false); + + auto userParameter = proto.add_user_parameter(); + userParameter->set_key("key1"); + userParameter->set_value("value1"); + + userParameter = proto.add_user_parameter(); + userParameter->set_key("key2"); + userParameter->set_value("value2"); + + BootParameters bootParameters = BootParameters(); + bootParameters.parseBootParameters(proto.SerializeAsString()); + + auto ¶meters = bootParameters.getParameters(); + ASSERT_EQ(2u, parameters.size()); + ASSERT_STREQ(parameters[0].key, "key1"); + ASSERT_STREQ(parameters[0].value, "value1"); + ASSERT_STREQ(parameters[1].key, "key2"); + ASSERT_STREQ(parameters[1].value, "value2"); +} + +TEST(BootParametersTest, TestParseLegacyDisableBootAnimationIsSilent) { + BootParameters bootParameters = BootParameters(); + bootParameters.parseLegacyBootParameters(R"( + { + "brightness":200, + "volume":100, + "boot_animation_disabled":1, + "param_names":[], + "param_values":[] + } + )"); + + ASSERT_TRUE(bootParameters.isSilentBoot()); +} + +TEST(BootParametersTest, TestParseLegacyZeroVolumeIsSilent) { + BootParameters bootParameters = BootParameters(); + bootParameters.parseLegacyBootParameters(R"( + { + "brightness":200, + "volume":0, + "boot_animation_disabled":0, + "param_names":[], + "param_values":[] + } + )"); + + ASSERT_TRUE(bootParameters.isSilentBoot()); +} + +TEST(BootParametersTest, TestParseLegacyDefaultVolumeIsSilent) { + BootParameters bootParameters = BootParameters(); + bootParameters.parseLegacyBootParameters(R"( + { + "brightness":200, + "volume":-1000, + "boot_animation_disabled":0, + "param_names":[], + "param_values":[] + } + )"); + + ASSERT_TRUE(bootParameters.isSilentBoot()); +} + +TEST(BootParametersTest, TestParseLegacyNotSilent) { + BootParameters bootParameters = BootParameters(); + bootParameters.parseLegacyBootParameters(R"( + { + "brightness":200, + "volume":500, + "boot_animation_disabled":0, + "param_names":[], + "param_values":[] + } + )"); + + ASSERT_FALSE(bootParameters.isSilentBoot()); +} + +TEST(BootParametersTest, TestParseLegacyParameters) { + BootParameters bootParameters = BootParameters(); + bootParameters.parseLegacyBootParameters(R"( + { + "brightness":200, + "volume":100, + "boot_animation_disabled":1, + "param_names":["key1", "key2"], + "param_values":["value1", "value2"] + } + )"); + + auto parameters = bootParameters.getParameters(); + ASSERT_EQ(2u, parameters.size()); + ASSERT_STREQ(parameters[0].key, "key1"); + ASSERT_STREQ(parameters[0].value, "value1"); + ASSERT_STREQ(parameters[1].key, "key2"); + ASSERT_STREQ(parameters[1].value, "value2"); +} + +TEST(BootParametersTest, TestParseLegacyZeroParameters) { + BootParameters bootParameters = BootParameters(); + bootParameters.parseLegacyBootParameters(R"( + { + "brightness":200, + "volume":100, + "boot_animation_disabled":1, + "param_names":[], + "param_values":[] + } + )"); + + ASSERT_EQ(0u, bootParameters.getParameters().size()); +} + +TEST(BootParametersTest, TestMalformedLegacyParametersAreSkipped) { + BootParameters bootParameters = BootParameters(); + bootParameters.parseLegacyBootParameters(R"( + { + "brightness":500, + "volume":500, + "boot_animation_disabled":0, + "param_names":["key1", "key2"], + "param_values":[1, "value2"] + } + )"); + + auto parameters = bootParameters.getParameters(); + ASSERT_EQ(1u, parameters.size()); + ASSERT_STREQ(parameters[0].key, "key2"); + ASSERT_STREQ(parameters[0].value, "value2"); +} + +TEST(BootParametersTest, TestLegacyUnequalParameterSizesAreSkipped) { + BootParameters bootParameters = BootParameters(); + bootParameters.parseLegacyBootParameters(R"( + { + "brightness":500, + "volume":500, + "boot_animation_disabled":0, + "param_names":["key1", "key2"], + "param_values":["value1"] + } + )"); + + ASSERT_EQ(0u, bootParameters.getParameters().size()); +} + +TEST(BootParametersTest, TestMissingLegacyBootParametersIsSilent) { + BootParameters bootParameters = BootParameters(); + bootParameters.parseLegacyBootParameters(R"( + { + "brightness":500 + } + )"); + + EXPECT_TRUE(bootParameters.isSilentBoot()); + ASSERT_EQ(0u, bootParameters.getParameters().size()); +} + +TEST(BootParametersTest, TestLastFileIsRemovedOnError) { + TemporaryFile lastFile; + TemporaryDir tempDir; + std::string nonExistentFilePath(std::string(tempDir.path) + "/nonexistent"); + std::string contents; + + BootParameters::swapAndLoadBootConfigContents(lastFile.path, nonExistentFilePath.c_str(), + &contents); + + struct stat buf; + ASSERT_EQ(-1, lstat(lastFile.path, &buf)); + ASSERT_TRUE(contents.empty()); +} + +TEST(BootParametersTest, TestNextFileIsRemovedLastFileExistsOnSuccess) { + TemporaryFile lastFile; + TemporaryFile nextFile; + + base::WriteStringToFile("foo", nextFile.path); + + std::string contents; + // Expected side effects: + // - |next_file| is moved to |last_file| + // - |contents| is the contents of |next_file| before being moved. + BootParameters::swapAndLoadBootConfigContents(lastFile.path, nextFile.path, &contents); + + struct stat buf; + ASSERT_EQ(0, lstat(lastFile.path, &buf)); + ASSERT_EQ(-1, lstat(nextFile.path, &buf)); + ASSERT_EQ(contents, "foo"); + + contents.clear(); + ASSERT_TRUE(base::ReadFileToString(lastFile.path, &contents)); + ASSERT_EQ(contents, "foo"); +} + +} // namespace + +} // namespace android diff --git a/cmds/bootanimation/iot/iotbootanimation_main.cpp b/cmds/bootanimation/iot/iotbootanimation_main.cpp index 00cef430135e..2a3d3766ab38 100644 --- a/cmds/bootanimation/iot/iotbootanimation_main.cpp +++ b/cmds/bootanimation/iot/iotbootanimation_main.cpp @@ -59,7 +59,7 @@ public: } mBootAction = new BootAction(); - if (!mBootAction->init(library_path, mBootParameters->getParameters())) { + if (!mBootAction->init(library_path, mBootParameters)) { mBootAction = NULL; } }; @@ -116,8 +116,16 @@ int main() { sp<ProcessState> proc(ProcessState::self()); ProcessState::self()->startThreadPool(); - sp<BootAnimation> boot = new BootAnimation( - new BootActionAnimationCallbacks(std::move(bootParameters))); + bool isSilentBoot = bootParameters->isSilentBoot(); + sp<BootActionAnimationCallbacks> callbacks = + new BootActionAnimationCallbacks(std::move(bootParameters)); + + // On silent boot, animations aren't displayed. + if (isSilentBoot) { + callbacks->init({}); + } else { + sp<BootAnimation> boot = new BootAnimation(callbacks); + } IPCThreadState::self()->joinThreadPool(); return 0; diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java index 6e0bd3a81d84..36e51b9703c9 100644 --- a/cmds/content/src/com/android/commands/content/Content.java +++ b/cmds/content/src/com/android/commands/content/Content.java @@ -462,7 +462,7 @@ public class Content { IBinder token = new Binder(); try { ContentProviderHolder holder = activityManager.getContentProviderExternal( - providerName, mUserId, token); + providerName, mUserId, token, "*cmd*"); if (holder == null) { throw new IllegalStateException("Could not find provider: " + providerName); } diff --git a/cmds/dpm/src/com/android/commands/dpm/Dpm.java b/cmds/dpm/src/com/android/commands/dpm/Dpm.java index 7c1a5557a1e9..376b13cd371e 100644 --- a/cmds/dpm/src/com/android/commands/dpm/Dpm.java +++ b/cmds/dpm/src/com/android/commands/dpm/Dpm.java @@ -46,6 +46,7 @@ public final class Dpm extends BaseCommand { private static final String COMMAND_SET_PROFILE_OWNER = "set-profile-owner"; private static final String COMMAND_REMOVE_ACTIVE_ADMIN = "remove-active-admin"; private static final String COMMAND_CLEAR_FREEZE_PERIOD_RECORD = "clear-freeze-period-record"; + private static final String COMMAND_FORCE_NETWORK_LOGS = "force-network-logs"; private static final String COMMAND_FORCE_SECURITY_LOGS = "force-security-logs"; private IDevicePolicyManager mDevicePolicyManager; @@ -84,6 +85,9 @@ public final class Dpm extends BaseCommand { "feature development to prevent triggering restriction on setting freeze " + "periods.\n" + "\n" + + "dpm " + COMMAND_FORCE_NETWORK_LOGS + ": makes all network logs available to " + + "the DPC and triggers DeviceAdminReceiver.onNetworkLogsAvailable() if needed.\n" + + "\n" + "dpm " + COMMAND_FORCE_SECURITY_LOGS + ": makes all security logs available to " + "the DPC and triggers DeviceAdminReceiver.onSecurityLogsAvailable() if needed."); } @@ -114,6 +118,9 @@ public final class Dpm extends BaseCommand { case COMMAND_CLEAR_FREEZE_PERIOD_RECORD: runClearFreezePeriodRecord(); break; + case COMMAND_FORCE_NETWORK_LOGS: + runForceNetworkLogs(); + break; case COMMAND_FORCE_SECURITY_LOGS: runForceSecurityLogs(); break; @@ -122,6 +129,18 @@ public final class Dpm extends BaseCommand { } } + private void runForceNetworkLogs() throws RemoteException, InterruptedException { + while (true) { + final long toWait = mDevicePolicyManager.forceNetworkLogs(); + if (toWait == 0) { + break; + } + System.out.println("We have to wait for " + toWait + " milliseconds..."); + Thread.sleep(toWait); + } + System.out.println("Success"); + } + private void runForceSecurityLogs() throws RemoteException, InterruptedException { while (true) { final long toWait = mDevicePolicyManager.forceSecurityLogs(); diff --git a/cmds/incident_helper/src/main.cpp b/cmds/incident_helper/src/main.cpp index 418dc3fad761..5b6ac7af539c 100644 --- a/cmds/incident_helper/src/main.cpp +++ b/cmds/incident_helper/src/main.cpp @@ -73,7 +73,8 @@ static TextParserBase* selectParser(int section) { case 2006: return new BatteryTypeParser(); default: - return NULL; + // Return no op parser when no specific ones are implemented. + return new NoopParser(); } } diff --git a/cmds/incidentd/src/FdBuffer.cpp b/cmds/incidentd/src/FdBuffer.cpp index 0885b13483c6..a8ef8311720d 100644 --- a/cmds/incidentd/src/FdBuffer.cpp +++ b/cmds/incidentd/src/FdBuffer.cpp @@ -71,7 +71,8 @@ status_t FdBuffer::read(int fd, int64_t timeout) { VLOG("return event has error %s", strerror(errno)); return errno != 0 ? -errno : UNKNOWN_ERROR; } else { - ssize_t amt = ::read(fd, mBuffer.writeBuffer(), mBuffer.currentToWrite()); + ssize_t amt = TEMP_FAILURE_RETRY( + ::read(fd, mBuffer.writeBuffer(), mBuffer.currentToWrite())); if (amt < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { continue; @@ -182,9 +183,9 @@ status_t FdBuffer::readProcessedDataInStream(int fd, unique_fd toFd, unique_fd f if (cirSize != BUFFER_SIZE && pfds[0].fd != -1) { ssize_t amt; if (rpos >= wpos) { - amt = ::read(fd, cirBuf + rpos, BUFFER_SIZE - rpos); + amt = TEMP_FAILURE_RETRY(::read(fd, cirBuf + rpos, BUFFER_SIZE - rpos)); } else { - amt = ::read(fd, cirBuf + rpos, wpos - rpos); + amt = TEMP_FAILURE_RETRY(::read(fd, cirBuf + rpos, wpos - rpos)); } if (amt < 0) { if (!(errno == EAGAIN || errno == EWOULDBLOCK)) { @@ -204,9 +205,9 @@ status_t FdBuffer::readProcessedDataInStream(int fd, unique_fd toFd, unique_fd f if (cirSize > 0 && pfds[1].fd != -1) { ssize_t amt; if (rpos > wpos) { - amt = ::write(toFd.get(), cirBuf + wpos, rpos - wpos); + amt = TEMP_FAILURE_RETRY(::write(toFd.get(), cirBuf + wpos, rpos - wpos)); } else { - amt = ::write(toFd.get(), cirBuf + wpos, BUFFER_SIZE - wpos); + amt = TEMP_FAILURE_RETRY(::write(toFd.get(), cirBuf + wpos, BUFFER_SIZE - wpos)); } if (amt < 0) { if (!(errno == EAGAIN || errno == EWOULDBLOCK)) { @@ -235,7 +236,8 @@ status_t FdBuffer::readProcessedDataInStream(int fd, unique_fd toFd, unique_fd f } // read from parsing process - ssize_t amt = ::read(fromFd.get(), mBuffer.writeBuffer(), mBuffer.currentToWrite()); + ssize_t amt = TEMP_FAILURE_RETRY( + ::read(fromFd.get(), mBuffer.writeBuffer(), mBuffer.currentToWrite())); if (amt < 0) { if (!(errno == EAGAIN || errno == EWOULDBLOCK)) { VLOG("Fail to read fromFd %d: %s", fromFd.get(), strerror(errno)); diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp index e305b5462b77..e92cf9444e15 100644 --- a/cmds/incidentd/src/IncidentService.cpp +++ b/cmds/incidentd/src/IncidentService.cpp @@ -314,6 +314,19 @@ status_t IncidentService::command(FILE* in, FILE* out, FILE* err, Vector<String8 mThrottler->dump(out); return NO_ERROR; } + if (!args[0].compare(String8("section"))) { + int id = atoi(args[1]); + int idx = 0; + while (SECTION_LIST[idx] != NULL) { + const Section* section = SECTION_LIST[idx]; + if (section->id == id) { + fprintf(out, "Section[%d] %s\n", id, section->name.string()); + break; + } + idx++; + } + return NO_ERROR; + } } return cmd_help(out); } @@ -321,8 +334,9 @@ status_t IncidentService::command(FILE* in, FILE* out, FILE* err, Vector<String8 status_t IncidentService::cmd_help(FILE* out) { fprintf(out, "usage: adb shell cmd incident privacy print <section_id>\n"); fprintf(out, "usage: adb shell cmd incident privacy parse <section_id> < proto.txt\n"); - fprintf(out, " Prints/parses for the section id.\n"); - fprintf(out, "\n"); + fprintf(out, " Prints/parses for the section id.\n\n"); + fprintf(out, "usage: adb shell cmd incident section <section_id>\n"); + fprintf(out, " Prints section id and its name.\n\n"); fprintf(out, "usage: adb shell cmd incident throttler\n"); fprintf(out, " Prints the current throttler state\n"); return NO_ERROR; diff --git a/cmds/incidentd/src/PrivacyBuffer.cpp b/cmds/incidentd/src/PrivacyBuffer.cpp index d753e5e6404e..7a8ebe394d51 100644 --- a/cmds/incidentd/src/PrivacyBuffer.cpp +++ b/cmds/incidentd/src/PrivacyBuffer.cpp @@ -86,8 +86,8 @@ status_t PrivacyBuffer::stripField(const Privacy* parentPolicy, const PrivacySpe // iterator will point to head of next field size_t currentAt = mData.rp()->pos(); writeFieldOrSkip(fieldTag, skip); - VLOG("[Depth %2d]Field %d %ss %d bytes", depth, fieldId, skip ? "skip" : "write", - (int)(get_varint_size(fieldTag) + mData.rp()->pos() - currentAt)); + VLOG("[Depth %2d]Field %d %ss %zu bytes", depth, fieldId, skip ? "skip" : "write", + get_varint_size(fieldTag) + mData.rp()->pos() - currentAt); return NO_ERROR; } // current field is message type and its sub-fields have extra privacy policies diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp index 4bbe04204a54..87799b38906c 100644 --- a/cmds/incidentd/src/Section.cpp +++ b/cmds/incidentd/src/Section.cpp @@ -151,11 +151,10 @@ DONE: } // ================================================================================ -Section::Section(int i, int64_t timeoutMs, bool userdebugAndEngOnly, bool deviceSpecific) +Section::Section(int i, int64_t timeoutMs, bool userdebugAndEngOnly) : id(i), timeoutMs(timeoutMs), - userdebugAndEngOnly(userdebugAndEngOnly), - deviceSpecific(deviceSpecific) {} + userdebugAndEngOnly(userdebugAndEngOnly) {} Section::~Section() {} @@ -240,10 +239,10 @@ status_t MetadataSection::Execute(ReportRequestSet* requests) const { // ================================================================================ static inline bool isSysfs(const char* filename) { return strncmp(filename, "/sys/", 5) == 0; } -FileSection::FileSection(int id, const char* filename, const bool deviceSpecific, - const int64_t timeoutMs) - : Section(id, timeoutMs, false, deviceSpecific), mFilename(filename) { - name = filename; +FileSection::FileSection(int id, const char* filename, const int64_t timeoutMs) + : Section(id, timeoutMs, false), mFilename(filename) { + name = "file "; + name += filename; mIsSysfs = isSysfs(filename); } @@ -254,8 +253,10 @@ status_t FileSection::Execute(ReportRequestSet* requests) const { // add O_CLOEXEC to make sure it is closed when exec incident helper unique_fd fd(open(mFilename, O_RDONLY | O_CLOEXEC)); if (fd.get() == -1) { - ALOGW("FileSection '%s' failed to open file", this->name.string()); - return this->deviceSpecific ? NO_ERROR : -errno; + ALOGW("[%s] failed to open file", this->name.string()); + // There may be some devices/architectures that won't have the file. + // Just return here without an error. + return NO_ERROR; } FdBuffer buffer; @@ -263,13 +264,13 @@ status_t FileSection::Execute(ReportRequestSet* requests) const { Fpipe c2pPipe; // initiate pipes to pass data to/from incident_helper if (!p2cPipe.init() || !c2pPipe.init()) { - ALOGW("FileSection '%s' failed to setup pipes", this->name.string()); + ALOGW("[%s] failed to setup pipes", this->name.string()); return -errno; } pid_t pid = fork_execute_incident_helper(this->id, &p2cPipe, &c2pPipe); if (pid == -1) { - ALOGW("FileSection '%s' failed to fork", this->name.string()); + ALOGW("[%s] failed to fork", this->name.string()); return -errno; } @@ -279,7 +280,7 @@ status_t FileSection::Execute(ReportRequestSet* requests) const { this->timeoutMs, mIsSysfs); write_section_stats(requests->sectionStats(this->id), buffer); if (readStatus != NO_ERROR || buffer.timedOut()) { - ALOGW("FileSection '%s' failed to read data from incident helper: %s, timedout: %s", + ALOGW("[%s] failed to read data from incident helper: %s, timedout: %s", this->name.string(), strerror(-readStatus), buffer.timedOut() ? "true" : "false"); kill_child(pid); return readStatus; @@ -287,20 +288,11 @@ status_t FileSection::Execute(ReportRequestSet* requests) const { status_t ihStatus = wait_child(pid); if (ihStatus != NO_ERROR) { - ALOGW("FileSection '%s' abnormal child process: %s", this->name.string(), - strerror(-ihStatus)); + ALOGW("[%s] abnormal child process: %s", this->name.string(), strerror(-ihStatus)); return ihStatus; } - VLOG("FileSection '%s' wrote %zd bytes in %d ms", this->name.string(), buffer.size(), - (int)buffer.durationMs()); - status_t err = write_report_requests(this->id, buffer, requests); - if (err != NO_ERROR) { - ALOGW("FileSection '%s' failed writing: %s", this->name.string(), strerror(-err)); - return err; - } - - return NO_ERROR; + return write_report_requests(this->id, buffer, requests); } // ================================================================================ GZipSection::GZipSection(int id, const char* filename, ...) : Section(id) { @@ -329,9 +321,8 @@ status_t GZipSection::Execute(ReportRequestSet* requests) const { ALOGW("GZipSection failed to open file %s", mFilenames[index]); index++; // look at the next file. } - VLOG("GZipSection is using file %s, fd=%d", mFilenames[index], fd.get()); if (fd.get() == -1) { - ALOGW("GZipSection %s can't open all the files", this->name.string()); + ALOGW("[%s] can't open all the files", this->name.string()); return NO_ERROR; // e.g. LAST_KMSG will reach here in user build. } FdBuffer buffer; @@ -339,13 +330,13 @@ status_t GZipSection::Execute(ReportRequestSet* requests) const { Fpipe c2pPipe; // initiate pipes to pass data to/from gzip if (!p2cPipe.init() || !c2pPipe.init()) { - ALOGW("GZipSection '%s' failed to setup pipes", this->name.string()); + ALOGW("[%s] failed to setup pipes", this->name.string()); return -errno; } pid_t pid = fork_execute_cmd((char* const*)GZIP, &p2cPipe, &c2pPipe); if (pid == -1) { - ALOGW("GZipSection '%s' failed to fork", this->name.string()); + ALOGW("[%s] failed to fork", this->name.string()); return -errno; } // parent process @@ -364,24 +355,22 @@ status_t GZipSection::Execute(ReportRequestSet* requests) const { size_t editPos = internalBuffer->wp()->pos(); internalBuffer->wp()->move(8); // reserve 8 bytes for the varint of the data size. size_t dataBeginAt = internalBuffer->wp()->pos(); - VLOG("GZipSection '%s' editPos=%zd, dataBeginAt=%zd", this->name.string(), editPos, - dataBeginAt); + VLOG("[%s] editPos=%zu, dataBeginAt=%zu", this->name.string(), editPos, dataBeginAt); status_t readStatus = buffer.readProcessedDataInStream( fd.get(), std::move(p2cPipe.writeFd()), std::move(c2pPipe.readFd()), this->timeoutMs, isSysfs(mFilenames[index])); write_section_stats(requests->sectionStats(this->id), buffer); if (readStatus != NO_ERROR || buffer.timedOut()) { - ALOGW("GZipSection '%s' failed to read data from gzip: %s, timedout: %s", - this->name.string(), strerror(-readStatus), buffer.timedOut() ? "true" : "false"); + ALOGW("[%s] failed to read data from gzip: %s, timedout: %s", this->name.string(), + strerror(-readStatus), buffer.timedOut() ? "true" : "false"); kill_child(pid); return readStatus; } status_t gzipStatus = wait_child(pid); if (gzipStatus != NO_ERROR) { - ALOGW("GZipSection '%s' abnormal child process: %s", this->name.string(), - strerror(-gzipStatus)); + ALOGW("[%s] abnormal child process: %s", this->name.string(), strerror(-gzipStatus)); return gzipStatus; } // Revisit the actual size from gzip result and edit the internal buffer accordingly. @@ -389,15 +378,8 @@ status_t GZipSection::Execute(ReportRequestSet* requests) const { internalBuffer->wp()->rewind()->move(editPos); internalBuffer->writeRawVarint32(dataSize); internalBuffer->copy(dataBeginAt, dataSize); - VLOG("GZipSection '%s' wrote %zd bytes in %d ms, dataSize=%zd", this->name.string(), - buffer.size(), (int)buffer.durationMs(), dataSize); - status_t err = write_report_requests(this->id, buffer, requests); - if (err != NO_ERROR) { - ALOGW("GZipSection '%s' failed writing: %s", this->name.string(), strerror(-err)); - return err; - } - return NO_ERROR; + return write_report_requests(this->id, buffer, requests); } // ================================================================================ @@ -482,8 +464,7 @@ status_t WorkerThreadSection::Execute(ReportRequestSet* requests) const { err = buffer.read(data->pipe.readFd().get(), this->timeoutMs); if (err != NO_ERROR) { // TODO: Log this error into the incident report. - ALOGW("WorkerThreadSection '%s' reader failed with error '%s'", this->name.string(), - strerror(-err)); + ALOGW("[%s] reader failed with error '%s'", this->name.string(), strerror(-err)); } // Done with the read fd. The worker thread closes the write one so @@ -501,39 +482,25 @@ status_t WorkerThreadSection::Execute(ReportRequestSet* requests) const { if (data->workerError != NO_ERROR) { err = data->workerError; // TODO: Log this error into the incident report. - ALOGW("WorkerThreadSection '%s' worker failed with error '%s'", this->name.string(), - strerror(-err)); + ALOGW("[%s] worker failed with error '%s'", this->name.string(), strerror(-err)); } } } write_section_stats(requests->sectionStats(this->id), buffer); if (timedOut || buffer.timedOut()) { - ALOGW("WorkerThreadSection '%s' timed out", this->name.string()); + ALOGW("[%s] timed out", this->name.string()); return NO_ERROR; } - if (buffer.truncated()) { - // TODO: Log this into the incident report. - } - // TODO: There was an error with the command or buffering. Report that. For now // just exit with a log messasge. if (err != NO_ERROR) { - ALOGW("WorkerThreadSection '%s' failed with error '%s'", this->name.string(), - strerror(-err)); + ALOGW("[%s] failed with error '%s'", this->name.string(), strerror(-err)); return NO_ERROR; } // Write the data that was collected - VLOG("WorkerThreadSection '%s' wrote %zd bytes in %d ms", name.string(), buffer.size(), - (int)buffer.durationMs()); - err = write_report_requests(this->id, buffer, requests); - if (err != NO_ERROR) { - ALOGW("WorkerThreadSection '%s' failed writing: '%s'", this->name.string(), strerror(-err)); - return err; - } - - return NO_ERROR; + return write_report_requests(this->id, buffer, requests); } // ================================================================================ @@ -570,18 +537,18 @@ status_t CommandSection::Execute(ReportRequestSet* requests) const { Fpipe ihPipe; if (!cmdPipe.init() || !ihPipe.init()) { - ALOGW("CommandSection '%s' failed to setup pipes", this->name.string()); + ALOGW("[%s] failed to setup pipes", this->name.string()); return -errno; } pid_t cmdPid = fork_execute_cmd((char* const*)mCommand, NULL, &cmdPipe); if (cmdPid == -1) { - ALOGW("CommandSection '%s' failed to fork", this->name.string()); + ALOGW("[%s] failed to fork", this->name.string()); return -errno; } pid_t ihPid = fork_execute_incident_helper(this->id, &cmdPipe, &ihPipe); if (ihPid == -1) { - ALOGW("CommandSection '%s' failed to fork", this->name.string()); + ALOGW("[%s] failed to fork", this->name.string()); return -errno; } @@ -589,7 +556,7 @@ status_t CommandSection::Execute(ReportRequestSet* requests) const { status_t readStatus = buffer.read(ihPipe.readFd().get(), this->timeoutMs); write_section_stats(requests->sectionStats(this->id), buffer); if (readStatus != NO_ERROR || buffer.timedOut()) { - ALOGW("CommandSection '%s' failed to read data from incident helper: %s, timedout: %s", + ALOGW("[%s] failed to read data from incident helper: %s, timedout: %s", this->name.string(), strerror(-readStatus), buffer.timedOut() ? "true" : "false"); kill_child(cmdPid); kill_child(ihPid); @@ -601,20 +568,13 @@ status_t CommandSection::Execute(ReportRequestSet* requests) const { status_t cmdStatus = wait_child(cmdPid); status_t ihStatus = wait_child(ihPid); if (cmdStatus != NO_ERROR || ihStatus != NO_ERROR) { - ALOGW("CommandSection '%s' abnormal child processes, return status: command: %s, incident " + ALOGW("[%s] abnormal child processes, return status: command: %s, incident " "helper: %s", this->name.string(), strerror(-cmdStatus), strerror(-ihStatus)); return cmdStatus != NO_ERROR ? cmdStatus : ihStatus; } - VLOG("CommandSection '%s' wrote %zd bytes in %d ms", this->name.string(), buffer.size(), - (int)buffer.durationMs()); - status_t err = write_report_requests(this->id, buffer, requests); - if (err != NO_ERROR) { - ALOGW("CommandSection '%s' failed writing: %s", this->name.string(), strerror(-err)); - return err; - } - return NO_ERROR; + return write_report_requests(this->id, buffer, requests); } // ================================================================================ @@ -664,7 +624,7 @@ status_t DumpsysSection::BlockingCall(int pipeWriteFd) const { map<log_id_t, log_time> LogSection::gLastLogsRetrieved; LogSection::LogSection(int id, log_id_t logID) : WorkerThreadSection(id), mLogID(logID) { - name += "logcat "; + name = "logcat "; name += android_log_id_to_name(logID); switch (logID) { case LOG_ID_EVENTS: @@ -705,7 +665,7 @@ status_t LogSection::BlockingCall(int pipeWriteFd) const { android_logger_list_free); if (android_logger_open(loggers.get(), mLogID) == NULL) { - ALOGE("LogSection %s: Can't get logger.", this->name.string()); + ALOGE("[%s] Can't get logger.", this->name.string()); return -1; } @@ -721,7 +681,7 @@ status_t LogSection::BlockingCall(int pipeWriteFd) const { // err = -EAGAIN, graceful indication for ANDRODI_LOG_NONBLOCK that this is the end of data. if (err <= 0) { if (err != -EAGAIN) { - ALOGW("LogSection %s: fails to read a log_msg.\n", this->name.string()); + ALOGW("[%s] fails to read a log_msg.\n", this->name.string()); } // dump previous logs and don't consider this error a failure. break; @@ -792,7 +752,7 @@ status_t LogSection::BlockingCall(int pipeWriteFd) const { AndroidLogEntry entry; err = android_log_processLogBuffer(&msg.entry_v1, &entry); if (err != NO_ERROR) { - ALOGW("LogSection %s: fails to process to an entry.\n", this->name.string()); + ALOGW("[%s] fails to process to an entry.\n", this->name.string()); break; } lastTimestamp.tv_sec = entry.tv_sec; @@ -821,7 +781,7 @@ status_t LogSection::BlockingCall(int pipeWriteFd) const { TombstoneSection::TombstoneSection(int id, const char* type, const int64_t timeoutMs) : WorkerThreadSection(id, timeoutMs), mType(type) { - name += "tombstone "; + name = "tombstone "; name += type; } @@ -876,7 +836,7 @@ status_t TombstoneSection::BlockingCall(int pipeWriteFd) const { Fpipe dumpPipe; if (!dumpPipe.init()) { - ALOGW("TombstoneSection '%s' failed to setup dump pipe", this->name.string()); + ALOGW("[%s] failed to setup dump pipe", this->name.string()); err = -errno; break; } @@ -910,7 +870,7 @@ status_t TombstoneSection::BlockingCall(int pipeWriteFd) const { // Wait on the child to avoid it becoming a zombie process. status_t cStatus = wait_child(child); if (err != NO_ERROR) { - ALOGW("TombstoneSection '%s' failed to read stack dump: %d", this->name.string(), err); + ALOGW("[%s] failed to read stack dump: %d", this->name.string(), err); dumpPipe.readFd().reset(); break; } diff --git a/cmds/incidentd/src/Section.h b/cmds/incidentd/src/Section.h index a031a15fe7c9..302b4ef7ae34 100644 --- a/cmds/incidentd/src/Section.h +++ b/cmds/incidentd/src/Section.h @@ -41,11 +41,9 @@ public: const int id; const int64_t timeoutMs; // each section must have a timeout const bool userdebugAndEngOnly; - const bool deviceSpecific; String8 name; - Section(int id, int64_t timeoutMs = REMOTE_CALL_TIMEOUT_MS, bool userdebugAndEngOnly = false, - bool deviceSpecific = false); + Section(int id, int64_t timeoutMs = REMOTE_CALL_TIMEOUT_MS, bool userdebugAndEngOnly = false); virtual ~Section(); virtual status_t Execute(ReportRequestSet* requests) const = 0; @@ -78,7 +76,7 @@ public: */ class FileSection : public Section { public: - FileSection(int id, const char* filename, bool deviceSpecific = false, + FileSection(int id, const char* filename, int64_t timeoutMs = 5000 /* 5 seconds */); virtual ~FileSection(); diff --git a/cmds/incidentd/src/Throttler.cpp b/cmds/incidentd/src/Throttler.cpp index 2b790ca14176..11136ecca091 100644 --- a/cmds/incidentd/src/Throttler.cpp +++ b/cmds/incidentd/src/Throttler.cpp @@ -18,6 +18,7 @@ #include "Throttler.h" +#include <inttypes.h> #include <utils/SystemClock.h> namespace android { @@ -42,15 +43,15 @@ bool Throttler::shouldThrottle() { } void Throttler::addReportSize(size_t reportByteSize) { - VLOG("The current request took %d bytes to dropbox", (int)reportByteSize); + VLOG("The current request took %zu bytes to dropbox", reportByteSize); mAccumulatedSize += reportByteSize; } void Throttler::dump(FILE* out) { - fprintf(out, "mSizeLimit=%d\n", (int)mSizeLimit); - fprintf(out, "mAccumulatedSize=%d\n", (int)mAccumulatedSize); - fprintf(out, "mRefractoryPeriodMs=%d\n", (int)mRefractoryPeriodMs); - fprintf(out, "mLastRefractoryMs=%d\n", (int)mLastRefractoryMs); + fprintf(out, "mSizeLimit=%zu\n", mSizeLimit); + fprintf(out, "mAccumulatedSize=%zu\n", mAccumulatedSize); + fprintf(out, "mRefractoryPeriodMs=%" PRIi64 "\n", mRefractoryPeriodMs); + fprintf(out, "mLastRefractoryMs=%" PRIi64 "\n", mLastRefractoryMs); } } // namespace incidentd diff --git a/cmds/incidentd/tests/Reporter_test.cpp b/cmds/incidentd/tests/Reporter_test.cpp index cf107c858cca..108690844280 100644 --- a/cmds/incidentd/tests/Reporter_test.cpp +++ b/cmds/incidentd/tests/Reporter_test.cpp @@ -176,7 +176,7 @@ TEST_F(ReporterTest, RunReportToGivenDirectory) { ASSERT_EQ(Reporter::REPORT_FINISHED, reporter->runReport(&size)); vector<string> results = InspectFiles(); - ASSERT_EQ((int)results.size(), 1); + ASSERT_EQ(results.size(), 1UL); EXPECT_EQ(results[0], "\n\x2" "\b\f\n\x6" diff --git a/cmds/incidentd/tests/Section_test.cpp b/cmds/incidentd/tests/Section_test.cpp index 3c338b3a36c8..9b684a060286 100644 --- a/cmds/incidentd/tests/Section_test.cpp +++ b/cmds/incidentd/tests/Section_test.cpp @@ -144,15 +144,15 @@ TEST_F(SectionTest, FileSection) { } TEST_F(SectionTest, FileSectionNotExist) { - FileSection fs1(NOOP_PARSER, "notexist", false, QUICK_TIMEOUT_MS); - ASSERT_EQ(NAME_NOT_FOUND, fs1.Execute(&requests)); + FileSection fs1(NOOP_PARSER, "notexist", QUICK_TIMEOUT_MS); + ASSERT_EQ(NO_ERROR, fs1.Execute(&requests)); - FileSection fs2(NOOP_PARSER, "notexist", true, QUICK_TIMEOUT_MS); + FileSection fs2(NOOP_PARSER, "notexist", QUICK_TIMEOUT_MS); ASSERT_EQ(NO_ERROR, fs2.Execute(&requests)); } TEST_F(SectionTest, FileSectionTimeout) { - FileSection fs(TIMEOUT_PARSER, tf.path, false, QUICK_TIMEOUT_MS); + FileSection fs(TIMEOUT_PARSER, tf.path, QUICK_TIMEOUT_MS); ASSERT_EQ(NO_ERROR, fs.Execute(&requests)); ASSERT_TRUE(requests.sectionStats(TIMEOUT_PARSER)->timed_out()); } diff --git a/cmds/input/src/com/android/commands/input/Input.java b/cmds/input/src/com/android/commands/input/Input.java index d3ec32076292..74edffb4738d 100644 --- a/cmds/input/src/com/android/commands/input/Input.java +++ b/cmds/input/src/com/android/commands/input/Input.java @@ -91,9 +91,6 @@ public class Input { if (args.length > start) { for (int i = start; i < args.length; i++) { int keyCode = KeyEvent.keyCodeFromString(args[i]); - if (keyCode == KeyEvent.KEYCODE_UNKNOWN) { - keyCode = KeyEvent.keyCodeFromString("KEYCODE_" + args[i]); - } sendKeyEvent(inputSource, keyCode, longpress); } return; diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk index 091268e15ad4..1c20bffd22cd 100644 --- a/cmds/statsd/Android.mk +++ b/cmds/statsd/Android.mk @@ -35,12 +35,13 @@ statsd_common_src := \ src/config/ConfigListener.cpp \ src/config/ConfigManager.cpp \ src/external/Perfetto.cpp \ + src/external/Perfprofd.cpp \ src/external/StatsPuller.cpp \ src/external/StatsCompanionServicePuller.cpp \ src/external/SubsystemSleepStatePuller.cpp \ src/external/ResourceHealthManagerPuller.cpp \ src/external/ResourceThermalManagerPuller.cpp \ - src/external/StatsPullerManagerImpl.cpp \ + src/external/StatsPullerManager.cpp \ src/external/puller_util.cpp \ src/logd/LogEvent.cpp \ src/logd/LogListener.cpp \ @@ -70,6 +71,11 @@ statsd_common_src := \ src/guardrail/StatsdStats.cpp \ src/socket/StatsSocketListener.cpp +# TODO(b/110563449): Once statsd is using a blueprint file, migrate to the proper filegroups. +statsd_common_src += \ + ../../../../system/extras/perfprofd/binder_interface/aidl/android/os/IPerfProfd.aidl \ + src/perfprofd/perfprofd_config.proto + statsd_common_c_includes := \ $(LOCAL_PATH)/src \ $(LOCAL_PATH)/../../libs/services/include @@ -141,10 +147,14 @@ LOCAL_SHARED_LIBRARIES := $(statsd_common_shared_libraries) \ LOCAL_MODULE_CLASS := EXECUTABLES -# Enable sanitizer and allow very verbose printing on eng builds +# Enable sanitizer ONLY on eng builds. ifeq ($(TARGET_BUILD_VARIANT),eng) LOCAL_CLANG := true LOCAL_SANITIZE := address +endif + +# Add a flag to enable stats log printing from statsd on debug builds. +ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT))) LOCAL_CFLAGS += \ -DVERY_VERBOSE_PRINTING endif @@ -247,6 +257,7 @@ LOCAL_SRC_FILES := \ src/stats_log.proto \ src/statsd_config.proto \ src/perfetto/perfetto_config.proto \ + src/perfprofd/perfprofd_config.proto \ src/atoms.proto LOCAL_PROTOC_OPTIMIZE_TYPE := lite diff --git a/cmds/statsd/benchmark/metric_util.cpp b/cmds/statsd/benchmark/metric_util.cpp index 50ed18d3e2b0..067b6eddf254 100644 --- a/cmds/statsd/benchmark/metric_util.cpp +++ b/cmds/statsd/benchmark/metric_util.cpp @@ -362,11 +362,12 @@ std::unique_ptr<LogEvent> CreateSyncEndEvent( sp<StatsLogProcessor> CreateStatsLogProcessor(const long timeBaseSec, const StatsdConfig& config, const ConfigKey& key) { sp<UidMap> uidMap = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> periodicAlarmMonitor; - sp<StatsLogProcessor> processor = new StatsLogProcessor( - uidMap, anomalyAlarmMonitor, periodicAlarmMonitor, timeBaseSec * NS_PER_SEC, - [](const ConfigKey&){return true;}); + sp<StatsLogProcessor> processor = + new StatsLogProcessor(uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, + timeBaseSec * NS_PER_SEC, [](const ConfigKey&) { return true; }); processor->OnConfigUpdated(timeBaseSec * NS_PER_SEC, key, config); return processor; } diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h index 02c49b99c583..b1d6ab338b9b 100644 --- a/cmds/statsd/src/FieldValue.h +++ b/cmds/statsd/src/FieldValue.h @@ -212,7 +212,7 @@ public: * the result is equal to the Matcher Field. That's a bit wise AND operation + check if 2 ints are * equal. Nothing can beat the performance of this matching algorithm. * - * TODO: ADD EXAMPLE HERE. + * TODO(b/110561213): ADD EXAMPLE HERE. */ struct Matcher { Matcher(const Field& matcher, int32_t mask) : mMatcher(matcher), mMask(mask){}; diff --git a/cmds/statsd/src/HashableDimensionKey.cpp b/cmds/statsd/src/HashableDimensionKey.cpp index 71030345b0aa..af8b3af6ea61 100644 --- a/cmds/statsd/src/HashableDimensionKey.cpp +++ b/cmds/statsd/src/HashableDimensionKey.cpp @@ -65,8 +65,6 @@ bool filterValues(const vector<Matcher>& matcherFields, const vector<FieldValue> for (const auto& value : values) { for (size_t i = 0; i < matcherFields.size(); ++i) { const auto& matcher = matcherFields[i]; - // TODO: potential optimization here to break early because all fields are naturally - // sorted. if (value.mField.matches(matcher)) { output->addValue(value); output->mutableValue(num_matches)->mField.setTag(value.mField.getTag()); @@ -196,4 +194,4 @@ bool MetricDimensionKey::operator<(const MetricDimensionKey& that) const { } // namespace statsd } // namespace os -} // namespace android
\ No newline at end of file +} // namespace android diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index e7f1caf26932..ab0aa25103e9 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -72,18 +72,20 @@ const int FIELD_ID_STRINGS = 9; #define STATS_DATA_DIR "/data/misc/stats-data" StatsLogProcessor::StatsLogProcessor(const sp<UidMap>& uidMap, + const sp<StatsPullerManager>& pullerManager, const sp<AlarmMonitor>& anomalyAlarmMonitor, const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs, const std::function<bool(const ConfigKey&)>& sendBroadcast) : mUidMap(uidMap), + mPullerManager(pullerManager), mAnomalyAlarmMonitor(anomalyAlarmMonitor), mPeriodicAlarmMonitor(periodicAlarmMonitor), mSendBroadcast(sendBroadcast), mTimeBaseNs(timeBaseNs), mLargestTimestampSeen(0), mLastTimestampSeen(0) { - mStatsPullerManager.ForceClearPullerCache(); + mPullerManager->ForceClearPullerCache(); } StatsLogProcessor::~StatsLogProcessor() { @@ -152,7 +154,7 @@ void StatsLogProcessor::onIsolatedUidChangedEventLocked(const LogEvent& event) { if (is_create) { mUidMap->assignIsolatedUid(isolated_uid, parent_uid); } else { - mUidMap->removeIsolatedUid(isolated_uid, parent_uid); + mUidMap->removeIsolatedUid(isolated_uid); } } else { ALOGE("Failed to parse uid in the isolated uid change event."); @@ -238,7 +240,7 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event, bool reconnected) { int64_t curTimeSec = getElapsedRealtimeSec(); if (curTimeSec - mLastPullerCacheClearTimeSec > StatsdStats::kPullerCacheClearIntervalSec) { - mStatsPullerManager.ClearPullerCacheIfNecessary(curTimeSec * NS_PER_SEC); + mPullerManager->ClearPullerCacheIfNecessary(curTimeSec * NS_PER_SEC); mLastPullerCacheClearTimeSec = curTimeSec; } @@ -266,8 +268,8 @@ void StatsLogProcessor::OnConfigUpdatedLocked( const int64_t timestampNs, const ConfigKey& key, const StatsdConfig& config) { VLOG("Updated configuration for key %s", key.ToString().c_str()); sp<MetricsManager> newMetricsManager = - new MetricsManager(key, config, mTimeBaseNs, timestampNs, mUidMap, - mAnomalyAlarmMonitor, mPeriodicAlarmMonitor); + new MetricsManager(key, config, mTimeBaseNs, timestampNs, mUidMap, mPullerManager, + mAnomalyAlarmMonitor, mPeriodicAlarmMonitor); if (newMetricsManager->isConfigValid()) { mUidMap->OnConfigUpdated(key); if (newMetricsManager->shouldAddUidMapListener()) { @@ -453,7 +455,7 @@ void StatsLogProcessor::OnConfigRemoved(const ConfigKey& key) { mLastBroadcastTimes.erase(key); if (mMetricsManagers.empty()) { - mStatsPullerManager.ForceClearPullerCache(); + mPullerManager->ForceClearPullerCache(); } } @@ -538,7 +540,7 @@ void StatsLogProcessor::WriteDataToDisk(const DumpReportReason dumpReportReason) void StatsLogProcessor::informPullAlarmFired(const int64_t timestampNs) { std::lock_guard<std::mutex> lock(mMetricsMutex); - mStatsPullerManager.OnAlarmFired(timestampNs); + mPullerManager->OnAlarmFired(timestampNs); } int64_t StatsLogProcessor::getLastReportTimeNs(const ConfigKey& key) { diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h index b175b3c544b5..05cf0c1fc764 100644 --- a/cmds/statsd/src/StatsLogProcessor.h +++ b/cmds/statsd/src/StatsLogProcessor.h @@ -45,7 +45,8 @@ enum DumpReportReason { class StatsLogProcessor : public ConfigListener { public: - StatsLogProcessor(const sp<UidMap>& uidMap, const sp<AlarmMonitor>& anomalyAlarmMonitor, + StatsLogProcessor(const sp<UidMap>& uidMap, const sp<StatsPullerManager>& pullerManager, + const sp<AlarmMonitor>& anomalyAlarmMonitor, const sp<AlarmMonitor>& subscriberTriggerAlarmMonitor, const int64_t timeBaseNs, const std::function<bool(const ConfigKey&)>& sendBroadcast); @@ -126,7 +127,7 @@ private: sp<UidMap> mUidMap; // Reference to the UidMap to lookup app name and version for each uid. - StatsPullerManager mStatsPullerManager; + sp<StatsPullerManager> mPullerManager; // Reference to StatsPullerManager sp<AlarmMonitor> mAnomalyAlarmMonitor; diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp index 10c04f67ca05..1119eb36c239 100644 --- a/cmds/statsd/src/StatsService.cpp +++ b/cmds/statsd/src/StatsService.cpp @@ -150,25 +150,26 @@ StatsService::StatsService(const sp<Looper>& handlerLooper) })) { mUidMap = new UidMap(); + mPullerManager = new StatsPullerManager(); StatsPuller::SetUidMap(mUidMap); mConfigManager = new ConfigManager(); - mProcessor = new StatsLogProcessor(mUidMap, mAnomalyAlarmMonitor, mPeriodicAlarmMonitor, - getElapsedRealtimeNs(), [this](const ConfigKey& key) { - sp<IStatsCompanionService> sc = getStatsCompanionService(); - auto receiver = mConfigManager->GetConfigReceiver(key); - if (sc == nullptr) { - VLOG("Could not find StatsCompanionService"); - return false; - } else if (receiver == nullptr) { - VLOG("Statscompanion could not find a broadcast receiver for %s", - key.ToString().c_str()); - return false; - } else { - sc->sendDataBroadcast(receiver, mProcessor->getLastReportTimeNs(key)); - return true; - } - } - ); + mProcessor = new StatsLogProcessor( + mUidMap, mPullerManager, mAnomalyAlarmMonitor, mPeriodicAlarmMonitor, + getElapsedRealtimeNs(), [this](const ConfigKey& key) { + sp<IStatsCompanionService> sc = getStatsCompanionService(); + auto receiver = mConfigManager->GetConfigReceiver(key); + if (sc == nullptr) { + VLOG("Could not find StatsCompanionService"); + return false; + } else if (receiver == nullptr) { + VLOG("Statscompanion could not find a broadcast receiver for %s", + key.ToString().c_str()); + return false; + } else { + sc->sendDataBroadcast(receiver, mProcessor->getLastReportTimeNs(key)); + return true; + } + }); mConfigManager->AddListener(mProcessor); @@ -439,7 +440,6 @@ status_t StatsService::cmd_trigger_broadcast(FILE* out, Vector<String8>& args) { if (argCount == 2) { // Automatically pick the UID uid = IPCThreadState::self()->getCallingUid(); - // TODO: What if this isn't a binder call? Should we fail? name.assign(args[1].c_str(), args[1].size()); good = true; } else if (argCount == 3) { @@ -492,7 +492,6 @@ status_t StatsService::cmd_config(FILE* in, FILE* out, FILE* err, Vector<String8 if (argCount == 3) { // Automatically pick the UID uid = IPCThreadState::self()->getCallingUid(); - // TODO: What if this isn't a binder call? Should we fail? name.assign(args[2].c_str(), args[2].size()); good = true; } else if (argCount == 4) { @@ -577,7 +576,6 @@ status_t StatsService::cmd_dump_report(FILE* out, FILE* err, const Vector<String if (argCount == 2) { // Automatically pick the UID uid = IPCThreadState::self()->getCallingUid(); - // TODO: What if this isn't a binder call? Should we fail? name.assign(args[1].c_str(), args[1].size()); good = true; } else if (argCount == 3) { @@ -603,7 +601,6 @@ status_t StatsService::cmd_dump_report(FILE* out, FILE* err, const Vector<String vector<uint8_t> data; mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), getElapsedRealtimeNs(), false /* include_current_bucket*/, ADB_DUMP, &data); - // TODO: print the returned StatsLogReport to file instead of printing to logcat. if (proto) { for (size_t i = 0; i < data.size(); i ++) { fprintf(out, "%c", data[i]); @@ -711,7 +708,7 @@ status_t StatsService::cmd_log_app_breadcrumb(FILE* out, const Vector<String8>& status_t StatsService::cmd_print_pulled_metrics(FILE* out, const Vector<String8>& args) { int s = atoi(args[1].c_str()); vector<shared_ptr<LogEvent> > stats; - if (mStatsPullerManager.Pull(s, getElapsedRealtimeNs(), &stats)) { + if (mPullerManager->Pull(s, getElapsedRealtimeNs(), &stats)) { for (const auto& it : stats) { fprintf(out, "Pull from %d: %s\n", s, it->ToString().c_str()); } @@ -739,7 +736,7 @@ status_t StatsService::cmd_clear_puller_cache(FILE* out) { VLOG("StatsService::cmd_clear_puller_cache with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid()); if (checkCallingPermission(String16(kPermissionDump))) { - int cleared = mStatsPullerManager.ForceClearPullerCache(); + int cleared = mPullerManager->ForceClearPullerCache(); fprintf(out, "Puller removed %d cached data!\n", cleared); return NO_ERROR; } else { @@ -870,7 +867,7 @@ Status StatsService::statsCompanionReady() { } VLOG("StatsService::statsCompanionReady linking to statsCompanion."); IInterface::asBinder(statsCompanion)->linkToDeath(this); - mStatsPullerManager.SetStatsCompanionService(statsCompanion); + mPullerManager->SetStatsCompanionService(statsCompanion); mAnomalyAlarmMonitor->setStatsCompanionService(statsCompanion); mPeriodicAlarmMonitor->setStatsCompanionService(statsCompanion); SubscriberReporter::getInstance().setStatsCompanionService(statsCompanion); @@ -1014,7 +1011,7 @@ void StatsService::binderDied(const wp <IBinder>& who) { mAnomalyAlarmMonitor->setStatsCompanionService(nullptr); mPeriodicAlarmMonitor->setStatsCompanionService(nullptr); SubscriberReporter::getInstance().setStatsCompanionService(nullptr); - mStatsPullerManager.SetStatsCompanionService(nullptr); + mPullerManager->SetStatsCompanionService(nullptr); } } // namespace statsd diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h index b3a477645b73..ed90050aae0b 100644 --- a/cmds/statsd/src/StatsService.h +++ b/cmds/statsd/src/StatsService.h @@ -49,7 +49,6 @@ public: virtual ~StatsService(); /** The anomaly alarm registered with AlarmManager won't be updated by less than this. */ - // TODO: Consider making this configurable. And choose a good number. const uint32_t MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS = 5; virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); @@ -246,9 +245,9 @@ private: sp<UidMap> mUidMap; /** - * Fetches external metrics. + * Fetches external metrics */ - StatsPullerManager mStatsPullerManager; + sp<StatsPullerManager> mPullerManager; /** * Tracks the configurations that have been passed to statsd. diff --git a/cmds/statsd/src/anomaly/AlarmMonitor.cpp b/cmds/statsd/src/anomaly/AlarmMonitor.cpp index 78f0c2b09537..bc36dadacddb 100644 --- a/cmds/statsd/src/anomaly/AlarmMonitor.cpp +++ b/cmds/statsd/src/anomaly/AlarmMonitor.cpp @@ -60,7 +60,7 @@ void AlarmMonitor::add(sp<const InternalAlarm> alarm) { ALOGW("Asked to add a 0-time alarm."); return; } - // TODO: Ensure that refractory period is respected. + // TODO(b/110563466): Ensure that refractory period is respected. VLOG("Adding alarm with time %u", alarm->timestampSec); mPq.push(alarm); if (mRegisteredAlarmTimeSec < 1 || diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp index f32efee56d64..ee111cddcfd7 100644 --- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp +++ b/cmds/statsd/src/anomaly/AnomalyTracker.cpp @@ -208,7 +208,8 @@ bool AnomalyTracker::detectAnomaly(const int64_t& currentBucketNum, } void AnomalyTracker::declareAnomaly(const int64_t& timestampNs, const MetricDimensionKey& key) { - // TODO: Why receive timestamp? RefractoryPeriod should always be based on real time right now. + // TODO(b/110563466): Why receive timestamp? RefractoryPeriod should always be based on + // real time right now. if (isInRefractoryPeriod(timestampNs, key)) { VLOG("Skipping anomaly declaration since within refractory period"); return; @@ -216,7 +217,8 @@ void AnomalyTracker::declareAnomaly(const int64_t& timestampNs, const MetricDime if (mAlert.has_refractory_period_secs()) { mRefractoryPeriodEndsSec[key] = ((timestampNs + NS_PER_SEC - 1) / NS_PER_SEC) // round up + mAlert.refractory_period_secs(); - // TODO: If we had access to the bucket_size_millis, consider calling resetStorage() + // TODO(b/110563466): If we had access to the bucket_size_millis, consider + // calling resetStorage() // if (mAlert.refractory_period_secs() > mNumOfPastBuckets * bucketSizeNs) {resetStorage();} } @@ -230,7 +232,7 @@ void AnomalyTracker::declareAnomaly(const int64_t& timestampNs, const MetricDime StatsdStats::getInstance().noteAnomalyDeclared(mConfigKey, mAlert.id()); - // TODO: This should also take in the const MetricDimensionKey& key? + // TODO(b/110564268): This should also take in the const MetricDimensionKey& key? android::util::stats_write(android::util::ANOMALY_DETECTED, mConfigKey.GetUid(), mConfigKey.GetId(), mAlert.id()); } diff --git a/cmds/statsd/src/anomaly/subscriber_util.cpp b/cmds/statsd/src/anomaly/subscriber_util.cpp index ee9e9c01a60a..9d37cdb2d4d7 100644 --- a/cmds/statsd/src/anomaly/subscriber_util.cpp +++ b/cmds/statsd/src/anomaly/subscriber_util.cpp @@ -22,6 +22,7 @@ #include <binder/IServiceManager.h> #include "external/Perfetto.h" +#include "external/Perfprofd.h" #include "frameworks/base/libs/incident/proto/android/os/header.pb.h" #include "subscriber/IncidentdReporter.h" #include "subscriber/SubscriberReporter.h" @@ -64,6 +65,12 @@ void triggerSubscribers(const int64_t rule_id, SubscriberReporter::getInstance().alertBroadcastSubscriber(configKey, subscription, dimensionKey); break; + case Subscription::SubscriberInformationCase::kPerfprofdDetails: + if (!CollectPerfprofdTraceAndUploadToDropbox(subscription.perfprofd_details(), + rule_id, configKey)) { + ALOGW("Failed to generate perfprofd traces."); + } + break; default: break; } diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index ab9c7e81a88e..cdb72ab7f174 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -579,7 +579,7 @@ message WakeupAlarmOccurred { * Changing from LOW to MEDIUM or HIGH can be considered the app waking the mobile radio. * * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java + * frameworks/base/services/core/java/com/android/server/NetworkManagementService.java */ message MobileRadioPowerStateChanged { repeated AttributionNode attribution_node = 1; @@ -593,7 +593,7 @@ message MobileRadioPowerStateChanged { * Changing from LOW to MEDIUM or HIGH can be considered the app waking the wifi radio. * * Logged from: - * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java + * frameworks/base/services/core/java/com/android/server/NetworkManagementService.java */ message WifiRadioPowerStateChanged { repeated AttributionNode attribution_node = 1; @@ -1484,6 +1484,7 @@ message ForegroundServiceStateChanged { message IsolatedUidChanged { // The host UID. Generally, we should attribute metrics from the isolated uid to the host uid. // NOTE: DO NOT annotate uid field in this atom. This atom is specially handled in statsd. + // This field is ignored when event == REMOVED. optional int32 parent_uid = 1; optional int32 isolated_uid = 2; diff --git a/cmds/statsd/src/external/Perfprofd.cpp b/cmds/statsd/src/external/Perfprofd.cpp new file mode 100644 index 000000000000..ff237e8f6317 --- /dev/null +++ b/cmds/statsd/src/external/Perfprofd.cpp @@ -0,0 +1,83 @@ +/* + * 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 "Perfprofd.h" + +#define DEBUG false // STOPSHIP if true +#include "config/ConfigKey.h" +#include "Log.h" + +#include <errno.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +#include <string> + +#include <binder/IServiceManager.h> + +#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" // Alert + +#include "android/os/IPerfProfd.h" + +namespace android { +namespace os { +namespace statsd { + +bool CollectPerfprofdTraceAndUploadToDropbox(const PerfprofdDetails& config, + int64_t alert_id, + const ConfigKey& configKey) { + VLOG("Starting trace collection through perfprofd"); + + if (!config.has_perfprofd_config()) { + ALOGE("The perfprofd trace config is empty, aborting"); + return false; + } + + sp<IPerfProfd> service = interface_cast<IPerfProfd>( + defaultServiceManager()->getService(android::String16("perfprofd"))); + if (service == NULL) { + ALOGE("Could not find perfprofd service"); + return false; + } + + // Add protobufs can't be described in AIDL, we need to re-serialize + // the config proto to send it. + std::vector<uint8_t> proto_serialized; + { + const auto& config_proto = config.perfprofd_config(); + int size = config_proto.ByteSize(); + proto_serialized.resize(size); + ::google::protobuf::uint8* target_ptr = + reinterpret_cast<::google::protobuf::uint8*>(proto_serialized.data()); + config_proto.SerializeWithCachedSizesToArray(target_ptr); + } + + // TODO: alert-id etc? + + binder::Status status = service->startProfilingProtobuf(proto_serialized); + if (status.isOk()) { + return true; + } + + ALOGE("Error starting perfprofd profiling: %s", status.toString8().c_str()); + return false; +} + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/external/Perfprofd.h b/cmds/statsd/src/external/Perfprofd.h new file mode 100644 index 000000000000..b93fdf8e1cb2 --- /dev/null +++ b/cmds/statsd/src/external/Perfprofd.h @@ -0,0 +1,38 @@ +/* + * 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. + */ + +#pragma once + +#include <inttypes.h> + +namespace android { +namespace os { +namespace statsd { + +class ConfigKey; +class PerfprofdDetails; // Declared in statsd_config.pb.h + +// Starts the collection of a Perfprofd trace with the given |config|. +// The trace is uploaded to Dropbox by the perfprofd service once done. +// This method returns immediately after passing the config and does NOT wait +// for the full duration of the trace. +bool CollectPerfprofdTraceAndUploadToDropbox(const PerfprofdDetails& config, + int64_t alert_id, + const ConfigKey& configKey); + +} // namespace statsd +} // namespace os +} // namespace android diff --git a/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp b/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp index 3741202763b3..ae97d7a2fc15 100644 --- a/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp +++ b/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp @@ -54,7 +54,7 @@ bool getHealthHal() { ResourceHealthManagerPuller::ResourceHealthManagerPuller(int tagId) : StatsPuller(tagId) { } -// TODO: add other health atoms (eg. Temperature). +// TODO(b/110565992): add other health atoms (eg. Temperature). bool ResourceHealthManagerPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) { if (!getHealthHal()) { ALOGE("Health Hal not loaded"); diff --git a/cmds/statsd/src/external/StatsPuller.cpp b/cmds/statsd/src/external/StatsPuller.cpp index b29e979b5236..436a8801896f 100644 --- a/cmds/statsd/src/external/StatsPuller.cpp +++ b/cmds/statsd/src/external/StatsPuller.cpp @@ -18,10 +18,10 @@ #include "Log.h" #include "StatsPuller.h" +#include "StatsPullerManager.h" #include "guardrail/StatsdStats.h" #include "puller_util.h" #include "stats_log_util.h" -#include "StatsPullerManagerImpl.h" namespace android { namespace os { @@ -35,7 +35,7 @@ void StatsPuller::SetUidMap(const sp<UidMap>& uidMap) { mUidMap = uidMap; } // ValueMetric has a minimum bucket size of 10min so that we don't pull too frequently StatsPuller::StatsPuller(const int tagId) : mTagId(tagId) { - mCoolDownNs = StatsPullerManagerImpl::kAllPullAtomInfo.find(tagId)->second.coolDownNs; + mCoolDownNs = StatsPullerManager::kAllPullAtomInfo.find(tagId)->second.coolDownNs; VLOG("Puller for tag %d created. Cooldown set to %lld", mTagId, (long long)mCoolDownNs); } diff --git a/cmds/statsd/src/external/StatsPullerManagerImpl.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp index c020f9c12b87..06edff9e498c 100644 --- a/cmds/statsd/src/external/StatsPullerManagerImpl.cpp +++ b/cmds/statsd/src/external/StatsPullerManager.cpp @@ -29,7 +29,7 @@ #include "ResourceHealthManagerPuller.h" #include "ResourceThermalManagerPuller.h" #include "StatsCompanionServicePuller.h" -#include "StatsPullerManagerImpl.h" +#include "StatsPullerManager.h" #include "SubsystemSleepStatePuller.h" #include "statslog.h" @@ -49,7 +49,7 @@ namespace statsd { // Values smaller than this may require to update the alarm. const int64_t NO_ALARM_UPDATE = INT64_MAX; -const std::map<int, PullAtomInfo> StatsPullerManagerImpl::kAllPullAtomInfo = { +const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = { // wifi_bytes_transfer {android::util::WIFI_BYTES_TRANSFER, {{2, 3, 4, 5}, @@ -173,10 +173,10 @@ const std::map<int, PullAtomInfo> StatsPullerManagerImpl::kAllPullAtomInfo = { // temperature {android::util::TEMPERATURE, {{}, {}, 1, new ResourceThermalManagerPuller()}}}; -StatsPullerManagerImpl::StatsPullerManagerImpl() : mNextPullTimeNs(NO_ALARM_UPDATE) { +StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) { } -bool StatsPullerManagerImpl::Pull(const int tagId, const int64_t timeNs, +bool StatsPullerManager::Pull(const int tagId, const int64_t timeNs, vector<shared_ptr<LogEvent>>* data) { VLOG("Initiating pulling %d", tagId); @@ -190,16 +190,11 @@ bool StatsPullerManagerImpl::Pull(const int tagId, const int64_t timeNs, } } -StatsPullerManagerImpl& StatsPullerManagerImpl::GetInstance() { - static StatsPullerManagerImpl instance; - return instance; -} - -bool StatsPullerManagerImpl::PullerForMatcherExists(int tagId) const { +bool StatsPullerManager::PullerForMatcherExists(int tagId) const { return kAllPullAtomInfo.find(tagId) != kAllPullAtomInfo.end(); } -void StatsPullerManagerImpl::updateAlarmLocked() { +void StatsPullerManager::updateAlarmLocked() { if (mNextPullTimeNs == NO_ALARM_UPDATE) { VLOG("No need to set alarms. Skipping"); return; @@ -214,7 +209,7 @@ void StatsPullerManagerImpl::updateAlarmLocked() { return; } -void StatsPullerManagerImpl::SetStatsCompanionService( +void StatsPullerManager::SetStatsCompanionService( sp<IStatsCompanionService> statsCompanionService) { AutoMutex _l(mLock); sp<IStatsCompanionService> tmpForLock = mStatsCompanionService; @@ -227,7 +222,7 @@ void StatsPullerManagerImpl::SetStatsCompanionService( } } -void StatsPullerManagerImpl::RegisterReceiver(int tagId, wp<PullDataReceiver> receiver, +void StatsPullerManager::RegisterReceiver(int tagId, wp<PullDataReceiver> receiver, int64_t nextPullTimeNs, int64_t intervalNs) { AutoMutex _l(mLock); auto& receivers = mReceivers[tagId]; @@ -262,7 +257,7 @@ void StatsPullerManagerImpl::RegisterReceiver(int tagId, wp<PullDataReceiver> re VLOG("Puller for tagId %d registered of %d", tagId, (int)receivers.size()); } -void StatsPullerManagerImpl::UnRegisterReceiver(int tagId, wp<PullDataReceiver> receiver) { +void StatsPullerManager::UnRegisterReceiver(int tagId, wp<PullDataReceiver> receiver) { AutoMutex _l(mLock); if (mReceivers.find(tagId) == mReceivers.end()) { VLOG("Unknown pull code or no receivers: %d", tagId); @@ -278,7 +273,7 @@ void StatsPullerManagerImpl::UnRegisterReceiver(int tagId, wp<PullDataReceiver> } } -void StatsPullerManagerImpl::OnAlarmFired(const int64_t currentTimeNs) { +void StatsPullerManager::OnAlarmFired(const int64_t currentTimeNs) { AutoMutex _l(mLock); int64_t minNextPullTimeNs = NO_ALARM_UPDATE; @@ -331,7 +326,7 @@ void StatsPullerManagerImpl::OnAlarmFired(const int64_t currentTimeNs) { updateAlarmLocked(); } -int StatsPullerManagerImpl::ForceClearPullerCache() { +int StatsPullerManager::ForceClearPullerCache() { int totalCleared = 0; for (const auto& pulledAtom : kAllPullAtomInfo) { totalCleared += pulledAtom.second.puller->ForceClearCache(); @@ -339,7 +334,7 @@ int StatsPullerManagerImpl::ForceClearPullerCache() { return totalCleared; } -int StatsPullerManagerImpl::ClearPullerCacheIfNecessary(int64_t timestampNs) { +int StatsPullerManager::ClearPullerCacheIfNecessary(int64_t timestampNs) { int totalCleared = 0; for (const auto& pulledAtom : kAllPullAtomInfo) { totalCleared += pulledAtom.second.puller->ClearCacheIfNecessary(timestampNs); diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h index 50ffe17549c6..45efc4a8bea0 100644 --- a/cmds/statsd/src/external/StatsPullerManager.h +++ b/cmds/statsd/src/external/StatsPullerManager.h @@ -16,54 +16,87 @@ #pragma once -#include "StatsPullerManagerImpl.h" +#include <android/os/IStatsCompanionService.h> +#include <binder/IServiceManager.h> +#include <utils/RefBase.h> +#include <utils/threads.h> +#include <list> +#include <string> +#include <unordered_map> +#include <vector> +#include "PullDataReceiver.h" +#include "StatsPuller.h" +#include "logd/LogEvent.h" namespace android { namespace os { namespace statsd { -class StatsPullerManager { - public: - virtual ~StatsPullerManager() {} +typedef struct { + // The field numbers of the fields that need to be summed when merging + // isolated uid with host uid. + std::vector<int> additiveFields; + // The field numbers of the fields that can't be merged when merging + // data belong to isolated uid and host uid. + std::vector<int> nonAdditiveFields; + // How long should the puller wait before doing an actual pull again. Default + // 1 sec. Set this to 0 if this is handled elsewhere. + int64_t coolDownNs = 1 * NS_PER_SEC; + // The actual puller + sp<StatsPuller> puller; +} PullAtomInfo; + +class StatsPullerManager : public virtual RefBase { +public: + StatsPullerManager(); + + virtual ~StatsPullerManager() { + } virtual void RegisterReceiver(int tagId, wp<PullDataReceiver> receiver, int64_t nextPullTimeNs, - int64_t intervalNs) { - mPullerManager.RegisterReceiver(tagId, receiver, nextPullTimeNs, intervalNs); - }; + int64_t intervalNs); - virtual void UnRegisterReceiver(int tagId, wp <PullDataReceiver> receiver) { - mPullerManager.UnRegisterReceiver(tagId, receiver); - }; + virtual void UnRegisterReceiver(int tagId, wp<PullDataReceiver> receiver); // Verify if we know how to pull for this matcher - bool PullerForMatcherExists(int tagId) { - return mPullerManager.PullerForMatcherExists(tagId); - } + bool PullerForMatcherExists(int tagId) const; - void OnAlarmFired(const int64_t currentTimeNs) { - mPullerManager.OnAlarmFired(currentTimeNs); - } + void OnAlarmFired(const int64_t timeNs); - virtual bool Pull(const int tagId, const int64_t timesNs, - vector<std::shared_ptr<LogEvent>>* data) { - return mPullerManager.Pull(tagId, timesNs, data); - } + virtual bool Pull(const int tagId, const int64_t timeNs, + vector<std::shared_ptr<LogEvent>>* data); - int ForceClearPullerCache() { - return mPullerManager.ForceClearPullerCache(); - } + int ForceClearPullerCache(); - void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService) { - mPullerManager.SetStatsCompanionService(statsCompanionService); - } + int ClearPullerCacheIfNecessary(int64_t timestampNs); - int ClearPullerCacheIfNecessary(int64_t timestampNs) { - return mPullerManager.ClearPullerCacheIfNecessary(timestampNs); - } + void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService); + + const static std::map<int, PullAtomInfo> kAllPullAtomInfo; + +private: + sp<IStatsCompanionService> mStatsCompanionService = nullptr; + + typedef struct { + int64_t nextPullTimeNs; + int64_t intervalNs; + wp<PullDataReceiver> receiver; + } ReceiverInfo; + + // mapping from simple matcher tagId to receivers + std::map<int, std::list<ReceiverInfo>> mReceivers; + + // locks for data receiver and StatsCompanionService changes + Mutex mLock; + + void updateAlarmLocked(); + + int64_t mNextPullTimeNs; - private: - StatsPullerManagerImpl - & mPullerManager = StatsPullerManagerImpl::GetInstance(); + FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents); + FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm); + FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents); + FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm); }; } // namespace statsd diff --git a/cmds/statsd/src/external/StatsPullerManagerImpl.h b/cmds/statsd/src/external/StatsPullerManagerImpl.h deleted file mode 100644 index 56d04b41c5d5..000000000000 --- a/cmds/statsd/src/external/StatsPullerManagerImpl.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2017 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. - */ - -#pragma once - -#include <android/os/IStatsCompanionService.h> -#include <binder/IServiceManager.h> -#include <utils/RefBase.h> -#include <utils/threads.h> -#include <string> -#include <unordered_map> -#include <vector> -#include <list> -#include "PullDataReceiver.h" -#include "StatsPuller.h" -#include "logd/LogEvent.h" - -namespace android { -namespace os { -namespace statsd { - -typedef struct { - // The field numbers of the fields that need to be summed when merging - // isolated uid with host uid. - std::vector<int> additiveFields; - // The field numbers of the fields that can't be merged when merging - // data belong to isolated uid and host uid. - std::vector<int> nonAdditiveFields; - // How long should the puller wait before doing an actual pull again. Default - // 1 sec. Set this to 0 if this is handled elsewhere. - int64_t coolDownNs = 1 * NS_PER_SEC; - // The actual puller - sp<StatsPuller> puller; -} PullAtomInfo; - -class StatsPullerManagerImpl : public virtual RefBase { -public: - static StatsPullerManagerImpl& GetInstance(); - - void RegisterReceiver(int tagId, wp<PullDataReceiver> receiver, int64_t nextPullTimeNs, - int64_t intervalNs); - - void UnRegisterReceiver(int tagId, wp<PullDataReceiver> receiver); - - // Verify if we know how to pull for this matcher - bool PullerForMatcherExists(int tagId) const; - - void OnAlarmFired(const int64_t timeNs); - - bool Pull(const int tagId, const int64_t timeNs, vector<std::shared_ptr<LogEvent>>* data); - - int ForceClearPullerCache(); - - int ClearPullerCacheIfNecessary(int64_t timestampNs); - - void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService); - - const static std::map<int, PullAtomInfo> kAllPullAtomInfo; - - private: - StatsPullerManagerImpl(); - - sp<IStatsCompanionService> mStatsCompanionService = nullptr; - - typedef struct { - int64_t nextPullTimeNs; - int64_t intervalNs; - wp<PullDataReceiver> receiver; - } ReceiverInfo; - - // mapping from simple matcher tagId to receivers - std::map<int, std::list<ReceiverInfo>> mReceivers; - - // locks for data receiver and StatsCompanionService changes - Mutex mLock; - - void updateAlarmLocked(); - - int64_t mNextPullTimeNs; - - FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents); - FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm); - FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents); - FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm); -}; - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/src/external/puller_util.cpp b/cmds/statsd/src/external/puller_util.cpp index 57fe10e51bfc..ea7fa972cb9c 100644 --- a/cmds/statsd/src/external/puller_util.cpp +++ b/cmds/statsd/src/external/puller_util.cpp @@ -17,7 +17,7 @@ #define DEBUG false // STOPSHIP if true #include "Log.h" -#include "StatsPullerManagerImpl.h" +#include "StatsPullerManager.h" #include "puller_util.h" #include "statslog.h" @@ -107,8 +107,8 @@ bool tryMerge(vector<shared_ptr<LogEvent>>& data, int child_pos, const vector<in */ void mergeIsolatedUidsToHostUid(vector<shared_ptr<LogEvent>>& data, const sp<UidMap>& uidMap, int tagId) { - if (StatsPullerManagerImpl::kAllPullAtomInfo.find(tagId) == - StatsPullerManagerImpl::kAllPullAtomInfo.end()) { + if (StatsPullerManager::kAllPullAtomInfo.find(tagId) == + StatsPullerManager::kAllPullAtomInfo.end()) { VLOG("Unknown pull atom id %d", tagId); return; } @@ -121,9 +121,9 @@ void mergeIsolatedUidsToHostUid(vector<shared_ptr<LogEvent>>& data, const sp<Uid uidField = it->second; // uidField is the field number in proto, } const vector<int>& additiveFields = - StatsPullerManagerImpl::kAllPullAtomInfo.find(tagId)->second.additiveFields; + StatsPullerManager::kAllPullAtomInfo.find(tagId)->second.additiveFields; const vector<int>& nonAdditiveFields = - StatsPullerManagerImpl::kAllPullAtomInfo.find(tagId)->second.nonAdditiveFields; + StatsPullerManager::kAllPullAtomInfo.find(tagId)->second.nonAdditiveFields; // map of host uid to their position in the original vector map<int, vector<int>> hostPosition; diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp index 764366fc420a..038cb954f578 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.cpp +++ b/cmds/statsd/src/guardrail/StatsdStats.cpp @@ -103,7 +103,6 @@ const std::map<int, std::pair<size_t, size_t>> StatsdStats::kAtomDimensionKeySiz {android::util::CPU_TIME_PER_UID_FREQ, {6000, 10000}}, }; -// TODO: add stats for pulled atoms. StatsdStats::StatsdStats() { mPushedAtomStats.resize(android::util::kMaxPushedAtomId + 1); mStartTimeSec = getWallClockSec(); diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h index 74541d37b840..9fb2cd813fb8 100644 --- a/cmds/statsd/src/guardrail/StatsdStats.h +++ b/cmds/statsd/src/guardrail/StatsdStats.h @@ -86,7 +86,6 @@ public: static StatsdStats& getInstance(); ~StatsdStats(){}; - // TODO: set different limit if the device is low ram. const static int kDimensionKeySizeSoftLimit = 500; const static int kDimensionKeySizeHardLimit = 800; diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp index 4e4f146d27ac..04d34f3be2c0 100644 --- a/cmds/statsd/src/logd/LogEvent.cpp +++ b/cmds/statsd/src/logd/LogEvent.cpp @@ -273,7 +273,7 @@ void LogEvent::init(android_log_context context) { } int64_t LogEvent::GetLong(size_t key, status_t* err) const { - // TODO: encapsulate the magical operations all in Field struct as a static function. + // TODO(b/110561208): encapsulate the magical operations in Field struct as static functions int field = getSimpleField(key); for (const auto& value : mValues) { if (value.mField.getField() == field) { diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp index e8904c625325..2f15d0fe0b71 100644 --- a/cmds/statsd/src/main.cpp +++ b/cmds/statsd/src/main.cpp @@ -29,6 +29,8 @@ #include <utils/Looper.h> #include <utils/StrongPointer.h> +#include <memory> + #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> @@ -72,7 +74,7 @@ static status_t start_log_reader_thread(const sp<StatsService>& service) { pthread_t thread; // Thread data. - log_reader_thread_data* data = new log_reader_thread_data(); + std::unique_ptr<log_reader_thread_data> data = std::make_unique<log_reader_thread_data>(); data->service = service; // Create the thread @@ -80,17 +82,20 @@ static status_t start_log_reader_thread(const sp<StatsService>& service) { if (err != NO_ERROR) { return err; } - // TODO: Do we need to tweak thread priority? err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); if (err != NO_ERROR) { pthread_attr_destroy(&attr); return err; } - err = pthread_create(&thread, &attr, log_reader_thread_func, static_cast<void*>(data)); + err = pthread_create(&thread, &attr, log_reader_thread_func, + static_cast<void*>(data.get())); if (err != NO_ERROR) { pthread_attr_destroy(&attr); return err; } + // Release here rather than in pthread_create, since an error creating the + // thread leaves `data` ownerless. + data.release(); pthread_attr_destroy(&attr); return NO_ERROR; diff --git a/cmds/statsd/src/matchers/LogMatchingTracker.h b/cmds/statsd/src/matchers/LogMatchingTracker.h index 4f30a047e256..88ab4e6f683a 100644 --- a/cmds/statsd/src/matchers/LogMatchingTracker.h +++ b/cmds/statsd/src/matchers/LogMatchingTracker.h @@ -86,8 +86,6 @@ protected: // The collection of the event tag ids that this LogMatchingTracker cares. So we can quickly // return kNotMatched when we receive an event with an id not in the list. This is especially // useful when we have a complex CombinationLogMatcherTracker. - // TODO: Consider use an array instead of stl set. In reality, the number of the tag ids a - // LogMatchingTracker cares is only a few. std::set<int> mAtomIds; }; diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp index 43f53e057000..a894782db9f7 100644 --- a/cmds/statsd/src/metrics/CountMetricProducer.cpp +++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp @@ -68,7 +68,6 @@ CountMetricProducer::CountMetricProducer(const ConfigKey& key, const CountMetric const sp<ConditionWizard>& wizard, const int64_t startTimeNs) : MetricProducer(metric.id(), key, startTimeNs, conditionIndex, wizard) { - // TODO: evaluate initial conditions. and set mConditionMet. if (metric.has_bucket()) { mBucketSizeNs = TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket()) * 1000000; diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h index 139c0838fef0..520d5de2b33f 100644 --- a/cmds/statsd/src/metrics/CountMetricProducer.h +++ b/cmds/statsd/src/metrics/CountMetricProducer.h @@ -40,7 +40,6 @@ struct CountBucket { class CountMetricProducer : public MetricProducer { public: - // TODO: Pass in the start time from MetricsManager, it should be consistent for all metrics. CountMetricProducer(const ConfigKey& key, const CountMetric& countMetric, const int conditionIndex, const sp<ConditionWizard>& wizard, const int64_t startTimeNs); @@ -80,7 +79,6 @@ private: void flushCurrentBucketLocked(const int64_t& eventTimeNs) override; - // TODO: Add a lock to mPastBuckets. std::unordered_map<MetricDimensionKey, std::vector<CountBucket>> mPastBuckets; // The current bucket (may be a partial bucket). diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp index 62237bc04642..a19eb0b66bc7 100644 --- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp +++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp @@ -76,9 +76,6 @@ DurationMetricProducer::DurationMetricProducer(const ConfigKey& key, const Durat mStopAllIndex(stopAllIndex), mNested(nesting), mContainANYPositionInInternalDimensions(false) { - // TODO: The following boiler plate code appears in all MetricProducers, but we can't abstract - // them in the base class, because the proto generated CountMetric, and DurationMetric are - // not related. Maybe we should add a template in the future?? if (metric.has_bucket()) { mBucketSizeNs = TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket()) * 1000000; @@ -434,8 +431,6 @@ void DurationMetricProducer::onConditionChangedLocked(const bool conditionMet, VLOG("Metric %lld onConditionChanged", (long long)mMetricId); mCondition = conditionMet; flushIfNeededLocked(eventTime); - // TODO: need to populate the condition change time from the event which triggers the condition - // change, instead of using current time. for (auto& whatIt : mCurrentSlicedDurationTrackerMap) { for (auto& pair : whatIt.second) { pair.second->onConditionChanged(conditionMet, eventTime); diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h index 88e455a3f1a1..c496b12df935 100644 --- a/cmds/statsd/src/metrics/DurationMetricProducer.h +++ b/cmds/statsd/src/metrics/DurationMetricProducer.h @@ -115,7 +115,6 @@ private: ConditionState mUnSlicedPartCondition; // Save the past buckets and we can clear when the StatsLogReport is dumped. - // TODO: Add a lock to mPastBuckets. std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>> mPastBuckets; // The duration trackers in the current bucket. diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h index 62d1105e0514..7f7aa3711255 100644 --- a/cmds/statsd/src/metrics/EventMetricProducer.h +++ b/cmds/statsd/src/metrics/EventMetricProducer.h @@ -33,7 +33,6 @@ namespace statsd { class EventMetricProducer : public MetricProducer { public: - // TODO: Pass in the start time from MetricsManager, it should be consistent for all metrics. EventMetricProducer(const ConfigKey& key, const EventMetric& eventMetric, const int conditionIndex, const sp<ConditionWizard>& wizard, const int64_t startTimeNs); diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp index aabd3616e2fe..a77941017c2d 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp @@ -72,9 +72,9 @@ GaugeMetricProducer::GaugeMetricProducer(const ConfigKey& key, const GaugeMetric const int conditionIndex, const sp<ConditionWizard>& wizard, const int pullTagId, const int64_t timeBaseNs, const int64_t startTimeNs, - shared_ptr<StatsPullerManager> statsPullerManager) + const sp<StatsPullerManager>& pullerManager) : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, wizard), - mStatsPullerManager(statsPullerManager), + mPullerManager(pullerManager), mPullTagId(pullTagId), mMinBucketSizeNs(metric.min_bucket_size_nanos()), mDimensionSoftLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) != @@ -101,7 +101,6 @@ GaugeMetricProducer::GaugeMetricProducer(const ConfigKey& key, const GaugeMetric translateFieldMatcher(metric.gauge_fields_filter().fields(), &mFieldMatchers); } - // TODO: use UidMap if uid->pkg_name is required if (metric.has_dimensions_in_what()) { translateFieldMatcher(metric.dimensions_in_what(), &mDimensionsInWhat); mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what()); @@ -127,8 +126,8 @@ GaugeMetricProducer::GaugeMetricProducer(const ConfigKey& key, const GaugeMetric flushIfNeededLocked(startTimeNs); // Kicks off the puller immediately. if (mPullTagId != -1 && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) { - mStatsPullerManager->RegisterReceiver( - mPullTagId, this, getCurrentBucketEndTimeNs(), mBucketSizeNs); + mPullerManager->RegisterReceiver(mPullTagId, this, getCurrentBucketEndTimeNs(), + mBucketSizeNs); } VLOG("Gauge metric %lld created. bucket size %lld start_time: %lld sliced %d", @@ -136,19 +135,10 @@ GaugeMetricProducer::GaugeMetricProducer(const ConfigKey& key, const GaugeMetric mConditionSliced); } -// for testing -GaugeMetricProducer::GaugeMetricProducer(const ConfigKey& key, const GaugeMetric& metric, - const int conditionIndex, - const sp<ConditionWizard>& wizard, const int pullTagId, - const int64_t timeBaseNs, const int64_t startTimeNs) - : GaugeMetricProducer(key, metric, conditionIndex, wizard, pullTagId, timeBaseNs, startTimeNs, - make_shared<StatsPullerManager>()) { -} - GaugeMetricProducer::~GaugeMetricProducer() { VLOG("~GaugeMetricProducer() called"); if (mPullTagId != -1 && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) { - mStatsPullerManager->UnRegisterReceiver(mPullTagId, this); + mPullerManager->UnRegisterReceiver(mPullTagId, this); } } @@ -308,7 +298,6 @@ void GaugeMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs, protoOutput->end(protoToken); mPastBuckets.clear(); - // TODO: Clear mDimensionKeyMap once the report is dumped. } void GaugeMetricProducer::pullLocked(const int64_t timestampNs) { @@ -336,7 +325,7 @@ void GaugeMetricProducer::pullLocked(const int64_t timestampNs) { } vector<std::shared_ptr<LogEvent>> allData; - if (!mStatsPullerManager->Pull(mPullTagId, timestampNs, &allData)) { + if (!mPullerManager->Pull(mPullTagId, timestampNs, &allData)) { ALOGE("Gauge Stats puller failed for tag: %d", mPullTagId); return; } diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h index c74f7927dfac..89b1f417b812 100644 --- a/cmds/statsd/src/metrics/GaugeMetricProducer.h +++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h @@ -58,7 +58,8 @@ class GaugeMetricProducer : public virtual MetricProducer, public virtual PullDa public: GaugeMetricProducer(const ConfigKey& key, const GaugeMetric& gaugeMetric, const int conditionIndex, const sp<ConditionWizard>& wizard, - const int pullTagId, const int64_t timeBaseNs, const int64_t startTimeNs); + const int pullTagId, const int64_t timeBaseNs, const int64_t startTimeNs, + const sp<StatsPullerManager>& pullerManager); virtual ~GaugeMetricProducer(); @@ -94,13 +95,6 @@ private: android::util::ProtoOutputStream* protoOutput) override; void clearPastBucketsLocked(const int64_t dumpTimeNs) override; - // for testing - GaugeMetricProducer(const ConfigKey& key, const GaugeMetric& gaugeMetric, - const int conditionIndex, const sp<ConditionWizard>& wizard, - const int pullTagId, - const int64_t timeBaseNs, const int64_t startTimeNs, - std::shared_ptr<StatsPullerManager> statsPullerManager); - // Internal interface to handle condition change. void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override; @@ -123,12 +117,11 @@ private: int mTagId; - std::shared_ptr<StatsPullerManager> mStatsPullerManager; + sp<StatsPullerManager> mPullerManager; // tagId for pulled data. -1 if this is not pulled const int mPullTagId; // Save the past buckets and we can clear when the StatsLogReport is dumped. - // TODO: Add a lock to mPastBuckets. std::unordered_map<MetricDimensionKey, std::vector<GaugeBucket>> mPastBuckets; // The current partial bucket. diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp index 4fac0e1a141b..0e5ef4d3e59a 100644 --- a/cmds/statsd/src/metrics/MetricsManager.cpp +++ b/cmds/statsd/src/metrics/MetricsManager.cpp @@ -56,10 +56,12 @@ const int FIELD_ID_ANNOTATIONS_INT32 = 2; MetricsManager::MetricsManager(const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, const int64_t currentTimeNs, - const sp<UidMap> &uidMap, + const sp<UidMap>& uidMap, + const sp<StatsPullerManager>& pullerManager, const sp<AlarmMonitor>& anomalyAlarmMonitor, const sp<AlarmMonitor>& periodicAlarmMonitor) - : mConfigKey(key), mUidMap(uidMap), + : mConfigKey(key), + mUidMap(uidMap), mTtlNs(config.has_ttl_in_seconds() ? config.ttl_in_seconds() * NS_PER_SEC : -1), mTtlEndNs(-1), mLastReportTimeNs(currentTimeNs), @@ -67,12 +69,11 @@ MetricsManager::MetricsManager(const ConfigKey& key, const StatsdConfig& config, // Init the ttl end timestamp. refreshTtl(timeBaseNs); - mConfigValid = - initStatsdConfig(key, config, *uidMap, anomalyAlarmMonitor, periodicAlarmMonitor, - timeBaseNs, currentTimeNs, mTagIds, mAllAtomMatchers, - mAllConditionTrackers, mAllMetricProducers, mAllAnomalyTrackers, - mAllPeriodicAlarmTrackers, mConditionToMetricMap, mTrackerToMetricMap, - mTrackerToConditionMap, mNoReportMetricIds); + mConfigValid = initStatsdConfig( + key, config, *uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, + timeBaseNs, currentTimeNs, mTagIds, mAllAtomMatchers, mAllConditionTrackers, + mAllMetricProducers, mAllAnomalyTrackers, mAllPeriodicAlarmTrackers, + mConditionToMetricMap, mTrackerToMetricMap, mTrackerToConditionMap, mNoReportMetricIds); mHashStringsInReport = config.hash_strings_in_metric_report(); @@ -237,7 +238,6 @@ void MetricsManager::onLogEvent(const LogEvent& event) { if (event.GetTagId() == android::util::APP_BREADCRUMB_REPORTED) { // Check that app breadcrumb reported fields are valid. - // TODO: Find a way to make these checks easier to maintain. status_t err = NO_ERROR; // Uid is 3rd from last field and must match the caller's uid, diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h index 6f4db48def86..dfbb69f1ab7c 100644 --- a/cmds/statsd/src/metrics/MetricsManager.h +++ b/cmds/statsd/src/metrics/MetricsManager.h @@ -16,6 +16,7 @@ #pragma once +#include "external/StatsPullerManager.h" #include "anomaly/AlarmMonitor.h" #include "anomaly/AlarmTracker.h" #include "anomaly/AnomalyTracker.h" @@ -36,9 +37,10 @@ namespace statsd { // A MetricsManager is responsible for managing metrics from one single config source. class MetricsManager : public PackageInfoListener { public: - MetricsManager(const ConfigKey& configKey, const StatsdConfig& config, - const int64_t timeBaseNs, const int64_t currentTimeNs, - const sp<UidMap>& uidMap, const sp<AlarmMonitor>& anomalyAlarmMonitor, + MetricsManager(const ConfigKey& configKey, const StatsdConfig& config, const int64_t timeBaseNs, + const int64_t currentTimeNs, const sp<UidMap>& uidMap, + const sp<StatsPullerManager>& pullerManager, + const sp<AlarmMonitor>& anomalyAlarmMonitor, const sp<AlarmMonitor>& periodicAlarmMonitor); virtual ~MetricsManager(); diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp index 41e55cb27f5e..f5e953a52630 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp +++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp @@ -74,10 +74,10 @@ ValueMetricProducer::ValueMetricProducer(const ConfigKey& key, const ValueMetric const int conditionIndex, const sp<ConditionWizard>& wizard, const int pullTagId, const int64_t timeBaseNs, const int64_t startTimestampNs, - shared_ptr<StatsPullerManager> statsPullerManager) + const sp<StatsPullerManager>& pullerManager) : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, wizard), + mPullerManager(pullerManager), mValueField(metric.value_field()), - mStatsPullerManager(statsPullerManager), mPullTagId(pullTagId), mMinBucketSizeNs(metric.min_bucket_size_nanos()), mDimensionSoftLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) != @@ -89,7 +89,6 @@ ValueMetricProducer::ValueMetricProducer(const ConfigKey& key, const ValueMetric ? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).second : StatsdStats::kDimensionKeySizeHardLimit), mUseAbsoluteValueOnReset(metric.use_absolute_value_on_reset()) { - // TODO: valuemetric for pushed events may need unlimited bucket length int64_t bucketSizeMills = 0; if (metric.has_bucket()) { bucketSizeMills = TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket()); @@ -127,27 +126,18 @@ ValueMetricProducer::ValueMetricProducer(const ConfigKey& key, const ValueMetric // Kicks off the puller immediately. flushIfNeededLocked(startTimestampNs); if (mPullTagId != -1) { - mStatsPullerManager->RegisterReceiver( - mPullTagId, this, mCurrentBucketStartTimeNs + mBucketSizeNs, mBucketSizeNs); + mPullerManager->RegisterReceiver(mPullTagId, this, + mCurrentBucketStartTimeNs + mBucketSizeNs, mBucketSizeNs); } VLOG("value metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(), (long long)mBucketSizeNs, (long long)mTimeBaseNs); } -// for testing -ValueMetricProducer::ValueMetricProducer(const ConfigKey& key, const ValueMetric& metric, - const int conditionIndex, - const sp<ConditionWizard>& wizard, const int pullTagId, - const int64_t timeBaseNs, const int64_t startTimeNs) - : ValueMetricProducer(key, metric, conditionIndex, wizard, pullTagId, timeBaseNs, startTimeNs, - make_shared<StatsPullerManager>()) { -} - ValueMetricProducer::~ValueMetricProducer() { VLOG("~ValueMetricProducer() called"); if (mPullTagId != -1) { - mStatsPullerManager->UnRegisterReceiver(mPullTagId, this); + mPullerManager->UnRegisterReceiver(mPullTagId, this); } } @@ -283,7 +273,7 @@ void ValueMetricProducer::onConditionChangedLocked(const bool condition, if (mPullTagId != -1) { vector<shared_ptr<LogEvent>> allData; - if (mStatsPullerManager->Pull(mPullTagId, eventTimeNs, &allData)) { + if (mPullerManager->Pull(mPullTagId, eventTimeNs, &allData)) { if (allData.size() == 0) { return; } diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h index cb6b051cd484..943d6dc4fe60 100644 --- a/cmds/statsd/src/metrics/ValueMetricProducer.h +++ b/cmds/statsd/src/metrics/ValueMetricProducer.h @@ -40,7 +40,8 @@ class ValueMetricProducer : public virtual MetricProducer, public virtual PullDa public: ValueMetricProducer(const ConfigKey& key, const ValueMetric& valueMetric, const int conditionIndex, const sp<ConditionWizard>& wizard, - const int pullTagId, const int64_t timeBaseNs, const int64_t startTimeNs); + const int pullTagId, const int64_t timeBaseNs, const int64_t startTimeNs, + const sp<StatsPullerManager>& pullerManager); virtual ~ValueMetricProducer(); @@ -53,7 +54,7 @@ public: if (mPullTagId != -1 && (mCondition == true || mConditionTrackerIndex < 0) ) { vector<shared_ptr<LogEvent>> allData; - mStatsPullerManager->Pull(mPullTagId, eventTimeNs, &allData); + mPullerManager->Pull(mPullTagId, eventTimeNs, &allData); if (allData.size() == 0) { // This shouldn't happen since this valuemetric is not useful now. } @@ -112,15 +113,9 @@ private: void dropDataLocked(const int64_t dropTimeNs) override; - const FieldMatcher mValueField; - - std::shared_ptr<StatsPullerManager> mStatsPullerManager; + sp<StatsPullerManager> mPullerManager; - // for testing - ValueMetricProducer(const ConfigKey& key, const ValueMetric& valueMetric, - const int conditionIndex, const sp<ConditionWizard>& wizard, - const int pullTagId, const int64_t timeBaseNs, const int64_t startTimeNs, - std::shared_ptr<StatsPullerManager> statsPullerManager); + const FieldMatcher mValueField; // tagId for pulled data. -1 if this is not pulled const int mPullTagId; @@ -149,7 +144,6 @@ private: std::unordered_map<MetricDimensionKey, int64_t> mCurrentFullBucket; // Save the past buckets and we can clear when the StatsLogReport is dumped. - // TODO: Add a lock to mPastBuckets. std::unordered_map<MetricDimensionKey, std::vector<ValueBucket>> mPastBuckets; // Pairs of (elapsed start, elapsed end) denoting buckets that were skipped. diff --git a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h index 149b3189dfba..ccb1d4359e89 100644 --- a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h +++ b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h @@ -44,7 +44,6 @@ struct DurationInfo { int64_t lastStartTime; // existing duration in current bucket. int64_t lastDuration; - // TODO: Optimize the way we track sliced condition in duration metrics. // cache the HashableDimensionKeys we need to query the condition for this duration event. ConditionKey conditionKeys; diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp index b833dfc79a22..956383a99eea 100644 --- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp +++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp @@ -326,7 +326,6 @@ void OringDurationTracker::onConditionChanged(bool condition, const int64_t time int64_t OringDurationTracker::predictAnomalyTimestampNs( const DurationAnomalyTracker& anomalyTracker, const int64_t eventTimestampNs) const { - // TODO: Unit-test this and see if it can be done more efficiently (e.g. use int32). // The anomaly threshold. const int64_t thresholdNs = anomalyTracker.getAnomalyThreshold(); diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp index 811a00e47ae5..e03edb3000ca 100644 --- a/cmds/statsd/src/metrics/metrics_manager_util.cpp +++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp @@ -103,7 +103,6 @@ bool handleMetricWithConditions( } allConditionTrackers[condition_it->second]->setSliced(true); allConditionTrackers[it->second]->setSliced(true); - // TODO: We need to verify the link is valid. } conditionIndex = condition_it->second; @@ -169,7 +168,6 @@ bool initLogTrackers(const StatsdConfig& config, const UidMap& uidMap, bool isStateTracker(const SimplePredicate& simplePredicate, vector<Matcher>* primaryKeys) { // 1. must not have "stop". must have "dimension" if (!simplePredicate.has_stop() && simplePredicate.has_dimensions()) { - // TODO: need to check the start atom matcher too. auto it = android::util::AtomsInfo::kStateAtomsFieldOptions.find( simplePredicate.dimensions().field()); // 2. must be based on a state atom. @@ -262,9 +260,10 @@ bool initConditions(const ConfigKey& key, const StatsdConfig& config, return true; } -bool initMetrics(const ConfigKey& key, const StatsdConfig& config, - const int64_t timeBaseTimeNs, const int64_t currentTimeNs, - UidMap& uidMap, const unordered_map<int64_t, int>& logTrackerMap, +bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseTimeNs, + const int64_t currentTimeNs, UidMap& uidMap, + const sp<StatsPullerManager>& pullerManager, + const unordered_map<int64_t, int>& logTrackerMap, const unordered_map<int64_t, int>& conditionTrackerMap, const vector<sp<LogMatchingTracker>>& allAtomMatchers, vector<sp<ConditionTracker>>& allConditionTrackers, @@ -465,9 +464,9 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, } } - sp<MetricProducer> valueProducer = new ValueMetricProducer(key, metric, conditionIndex, - wizard, pullTagId, - timeBaseTimeNs, currentTimeNs); + sp<MetricProducer> valueProducer = + new ValueMetricProducer(key, metric, conditionIndex, wizard, pullTagId, + timeBaseTimeNs, currentTimeNs, pullerManager); allMetricProducers.push_back(valueProducer); } @@ -525,8 +524,9 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, } } - sp<MetricProducer> gaugeProducer = new GaugeMetricProducer( - key, metric, conditionIndex, wizard, pullTagId, timeBaseTimeNs, currentTimeNs); + sp<MetricProducer> gaugeProducer = + new GaugeMetricProducer(key, metric, conditionIndex, wizard, pullTagId, + timeBaseTimeNs, currentTimeNs, pullerManager); allMetricProducers.push_back(gaugeProducer); } for (int i = 0; i < config.no_report_metric_size(); ++i) { @@ -645,10 +645,10 @@ bool initAlarms(const StatsdConfig& config, const ConfigKey& key, } bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& uidMap, + const sp<StatsPullerManager>& pullerManager, const sp<AlarmMonitor>& anomalyAlarmMonitor, - const sp<AlarmMonitor>& periodicAlarmMonitor, - const int64_t timeBaseNs, const int64_t currentTimeNs, - set<int>& allTagIds, + const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs, + const int64_t currentTimeNs, set<int>& allTagIds, vector<sp<LogMatchingTracker>>& allAtomMatchers, vector<sp<ConditionTracker>>& allConditionTrackers, vector<sp<MetricProducer>>& allMetricProducers, @@ -674,9 +674,8 @@ bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& return false; } - if (!initMetrics(key, config, timeBaseNs, currentTimeNs, uidMap, - logTrackerMap, conditionTrackerMap, - allAtomMatchers, allConditionTrackers, allMetricProducers, + if (!initMetrics(key, config, timeBaseNs, currentTimeNs, uidMap, pullerManager, logTrackerMap, + conditionTrackerMap, allAtomMatchers, allConditionTrackers, allMetricProducers, conditionToMetricMap, trackerToMetricMap, metricProducerMap, noReportMetricIds)) { ALOGE("initMetricProducers failed"); diff --git a/cmds/statsd/src/metrics/metrics_manager_util.h b/cmds/statsd/src/metrics/metrics_manager_util.h index d749bf43c9be..c6601493135f 100644 --- a/cmds/statsd/src/metrics/metrics_manager_util.h +++ b/cmds/statsd/src/metrics/metrics_manager_util.h @@ -23,7 +23,7 @@ #include "../anomaly/AlarmTracker.h" #include "../condition/ConditionTracker.h" -#include "../external/StatsPullerManagerImpl.h" +#include "../external/StatsPullerManager.h" #include "../matchers/LogMatchingTracker.h" #include "../metrics/MetricProducer.h" @@ -81,9 +81,8 @@ bool initConditions(const ConfigKey& key, const StatsdConfig& config, // the list of MetricProducer index // [trackerToMetricMap]: contains the mapping from log tracker to MetricProducer index. bool initMetrics( - const ConfigKey& key, const StatsdConfig& config, - const int64_t timeBaseTimeNs, const int64_t currentTimeNs, - UidMap& uidMap, + const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseTimeNs, + const int64_t currentTimeNs, UidMap& uidMap, const sp<StatsPullerManager>& pullerManager, const std::unordered_map<int64_t, int>& logTrackerMap, const std::unordered_map<int64_t, int>& conditionTrackerMap, const std::unordered_map<int, std::vector<MetricConditionLink>>& eventConditionLinks, @@ -97,10 +96,10 @@ bool initMetrics( // Initialize MetricsManager from StatsdConfig. // Parameters are the members of MetricsManager. See MetricsManager for declaration. bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& uidMap, + const sp<StatsPullerManager>& pullerManager, const sp<AlarmMonitor>& anomalyAlarmMonitor, - const sp<AlarmMonitor>& periodicAlarmMonitor, - const int64_t timeBaseNs, const int64_t currentTimeNs, - std::set<int>& allTagIds, + const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs, + const int64_t currentTimeNs, std::set<int>& allTagIds, std::vector<sp<LogMatchingTracker>>& allAtomMatchers, std::vector<sp<ConditionTracker>>& allConditionTrackers, std::vector<sp<MetricProducer>>& allMetricProducers, diff --git a/cmds/statsd/src/packages/UidMap.cpp b/cmds/statsd/src/packages/UidMap.cpp index fff909c12441..be94725991af 100644 --- a/cmds/statsd/src/packages/UidMap.cpp +++ b/cmds/statsd/src/packages/UidMap.cpp @@ -272,7 +272,7 @@ void UidMap::assignIsolatedUid(int isolatedUid, int parentUid) { mIsolatedUidMap[isolatedUid] = parentUid; } -void UidMap::removeIsolatedUid(int isolatedUid, int parentUid) { +void UidMap::removeIsolatedUid(int isolatedUid) { lock_guard<mutex> lock(mIsolatedMutex); auto it = mIsolatedUidMap.find(isolatedUid); diff --git a/cmds/statsd/src/packages/UidMap.h b/cmds/statsd/src/packages/UidMap.h index 5e42cd18de32..91f203084388 100644 --- a/cmds/statsd/src/packages/UidMap.h +++ b/cmds/statsd/src/packages/UidMap.h @@ -119,7 +119,7 @@ public: void OnConfigRemoved(const ConfigKey& key); void assignIsolatedUid(int isolatedUid, int parentUid); - void removeIsolatedUid(int isolatedUid, int parentUid); + void removeIsolatedUid(int isolatedUid); // Returns the host uid if it exists. Otherwise, returns the same uid that was passed-in. virtual int getHostUidOrSelf(int uid) const; @@ -146,7 +146,6 @@ private: void getListenerListCopyLocked(std::vector<wp<PackageInfoListener>>* output); - // TODO: Use shared_mutex for improved read-locking if a library can be found in Android. mutable mutex mMutex; mutable mutex mIsolatedMutex; diff --git a/cmds/statsd/src/perfprofd/perfprofd_config.proto b/cmds/statsd/src/perfprofd/perfprofd_config.proto new file mode 120000 index 000000000000..c8be24707dfd --- /dev/null +++ b/cmds/statsd/src/perfprofd/perfprofd_config.proto @@ -0,0 +1 @@ +../../../../../../system/extras/perfprofd/perfprofd_config.proto
\ No newline at end of file diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto index cf5530000555..638fbb98120d 100644 --- a/cmds/statsd/src/statsd_config.proto +++ b/cmds/statsd/src/statsd_config.proto @@ -22,6 +22,7 @@ option java_package = "com.android.internal.os"; option java_outer_classname = "StatsdConfigProto"; import "frameworks/base/cmds/statsd/src/perfetto/perfetto_config.proto"; +import "frameworks/base/cmds/statsd/src/perfprofd/perfprofd_config.proto"; enum Position { POSITION_UNKNOWN = 0; @@ -303,6 +304,10 @@ message PerfettoDetails { optional perfetto.protos.TraceConfig trace_config = 1; } +message PerfprofdDetails { + optional android.perfprofd.ProfilingConfig perfprofd_config = 1; +} + message BroadcastSubscriberDetails { optional int64 subscriber_id = 1; repeated string cookie = 2; @@ -324,6 +329,7 @@ message Subscription { IncidentdDetails incidentd_details = 4; PerfettoDetails perfetto_details = 5; BroadcastSubscriberDetails broadcast_subscriber_details = 6; + PerfprofdDetails perfprofd_details = 8; } optional float probability_of_informing = 7 [default = 1.1]; diff --git a/cmds/statsd/src/storage/StorageManager.cpp b/cmds/statsd/src/storage/StorageManager.cpp index 1f8181266b65..3ebc8a492d68 100644 --- a/cmds/statsd/src/storage/StorageManager.cpp +++ b/cmds/statsd/src/storage/StorageManager.cpp @@ -57,7 +57,7 @@ static void parseFileName(char* name, int64_t* result) { } // When index ends before hitting 3, file name is corrupted. We // intentionally put -1 at index 0 to indicate the error to caller. - // TODO: consider removing files with unexpected name format. + // TODO(b/110563137): consider removing files with unexpected name format. if (index < 3) { result[0] = -1; } diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp index c253bc19d641..a9305accb1be 100644 --- a/cmds/statsd/tests/FieldValue_test.cpp +++ b/cmds/statsd/tests/FieldValue_test.cpp @@ -312,7 +312,8 @@ TEST(AtomMatcherTest, TestSubscriberDimensionWrite) { dim.addValue(FieldValue(field4, value4)); SubscriberReporter::getStatsDimensionsValue(dim); - // TODO: can't test anything here because SubscriberReport class doesn't have any read api. + // TODO(b/110562792): can't test anything here because StatsDimensionsValue class doesn't + // have any read api. } TEST(AtomMatcherTest, TestWriteDimensionToProto) { @@ -483,4 +484,4 @@ TEST(AtomMatcherTest, TestWriteAtomToProto) { } // namespace android #else GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif
\ No newline at end of file +#endif diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp index 07378dbcce1a..8fbb58a956d5 100644 --- a/cmds/statsd/tests/MetricsManager_test.cpp +++ b/cmds/statsd/tests/MetricsManager_test.cpp @@ -39,8 +39,6 @@ using android::os::statsd::Predicate; #ifdef __ANDROID__ -// TODO: ADD MORE TEST CASES. - const ConfigKey kConfigKey(0, 12345); const long timeBaseSec = 1000; @@ -271,6 +269,7 @@ StatsdConfig buildCirclePredicates() { TEST(MetricsManagerTest, TestGoodConfig) { UidMap uidMap; + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> periodicAlarmMonitor; StatsdConfig config = buildGoodConfig(); @@ -285,13 +284,11 @@ TEST(MetricsManagerTest, TestGoodConfig) { unordered_map<int, std::vector<int>> trackerToConditionMap; std::set<int64_t> noReportMetricIds; - EXPECT_TRUE(initStatsdConfig(kConfigKey, config, uidMap, - anomalyAlarmMonitor, periodicAlarmMonitor, - timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, - allConditionTrackers, allMetricProducers, allAnomalyTrackers, - allAlarmTrackers, - conditionToMetricMap, trackerToMetricMap, trackerToConditionMap, - noReportMetricIds)); + EXPECT_TRUE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, + periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds, + allAtomMatchers, allConditionTrackers, allMetricProducers, + allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, + trackerToMetricMap, trackerToConditionMap, noReportMetricIds)); EXPECT_EQ(1u, allMetricProducers.size()); EXPECT_EQ(1u, allAnomalyTrackers.size()); EXPECT_EQ(1u, noReportMetricIds.size()); @@ -299,6 +296,7 @@ TEST(MetricsManagerTest, TestGoodConfig) { TEST(MetricsManagerTest, TestDimensionMetricsWithMultiTags) { UidMap uidMap; + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> periodicAlarmMonitor; StatsdConfig config = buildDimensionMetricsWithMultiTags(); @@ -313,17 +311,16 @@ TEST(MetricsManagerTest, TestDimensionMetricsWithMultiTags) { unordered_map<int, std::vector<int>> trackerToConditionMap; std::set<int64_t> noReportMetricIds; - EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, - anomalyAlarmMonitor, periodicAlarmMonitor, - timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, - allConditionTrackers, allMetricProducers, allAnomalyTrackers, - allAlarmTrackers, - conditionToMetricMap, trackerToMetricMap, trackerToConditionMap, - noReportMetricIds)); + EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, + periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds, + allAtomMatchers, allConditionTrackers, allMetricProducers, + allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, + trackerToMetricMap, trackerToConditionMap, noReportMetricIds)); } TEST(MetricsManagerTest, TestCircleLogMatcherDependency) { UidMap uidMap; + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> periodicAlarmMonitor; StatsdConfig config = buildCircleMatchers(); @@ -338,17 +335,16 @@ TEST(MetricsManagerTest, TestCircleLogMatcherDependency) { unordered_map<int, std::vector<int>> trackerToConditionMap; std::set<int64_t> noReportMetricIds; - EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, - anomalyAlarmMonitor, periodicAlarmMonitor, - timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, - allConditionTrackers, allMetricProducers, allAnomalyTrackers, - allAlarmTrackers, - conditionToMetricMap, trackerToMetricMap, trackerToConditionMap, - noReportMetricIds)); + EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, + periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds, + allAtomMatchers, allConditionTrackers, allMetricProducers, + allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, + trackerToMetricMap, trackerToConditionMap, noReportMetricIds)); } TEST(MetricsManagerTest, TestMissingMatchers) { UidMap uidMap; + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> periodicAlarmMonitor; StatsdConfig config = buildMissingMatchers(); @@ -362,17 +358,16 @@ TEST(MetricsManagerTest, TestMissingMatchers) { unordered_map<int, std::vector<int>> trackerToMetricMap; unordered_map<int, std::vector<int>> trackerToConditionMap; std::set<int64_t> noReportMetricIds; - EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, - anomalyAlarmMonitor, periodicAlarmMonitor, - timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, - allConditionTrackers, allMetricProducers, allAnomalyTrackers, - allAlarmTrackers, - conditionToMetricMap, trackerToMetricMap, trackerToConditionMap, - noReportMetricIds)); + EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, + periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds, + allAtomMatchers, allConditionTrackers, allMetricProducers, + allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, + trackerToMetricMap, trackerToConditionMap, noReportMetricIds)); } TEST(MetricsManagerTest, TestMissingPredicate) { UidMap uidMap; + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> periodicAlarmMonitor; StatsdConfig config = buildMissingPredicate(); @@ -386,17 +381,16 @@ TEST(MetricsManagerTest, TestMissingPredicate) { unordered_map<int, std::vector<int>> trackerToMetricMap; unordered_map<int, std::vector<int>> trackerToConditionMap; std::set<int64_t> noReportMetricIds; - EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, - anomalyAlarmMonitor, periodicAlarmMonitor, - timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, - allConditionTrackers, allMetricProducers, allAnomalyTrackers, - allAlarmTrackers, - conditionToMetricMap, trackerToMetricMap, trackerToConditionMap, - noReportMetricIds)); + EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, + periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds, + allAtomMatchers, allConditionTrackers, allMetricProducers, + allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, + trackerToMetricMap, trackerToConditionMap, noReportMetricIds)); } TEST(MetricsManagerTest, TestCirclePredicateDependency) { UidMap uidMap; + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> periodicAlarmMonitor; StatsdConfig config = buildCirclePredicates(); @@ -411,17 +405,16 @@ TEST(MetricsManagerTest, TestCirclePredicateDependency) { unordered_map<int, std::vector<int>> trackerToConditionMap; std::set<int64_t> noReportMetricIds; - EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, - anomalyAlarmMonitor, periodicAlarmMonitor, - timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, - allConditionTrackers, allMetricProducers, allAnomalyTrackers, - allAlarmTrackers, - conditionToMetricMap, trackerToMetricMap, trackerToConditionMap, - noReportMetricIds)); + EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, + periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds, + allAtomMatchers, allConditionTrackers, allMetricProducers, + allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, + trackerToMetricMap, trackerToConditionMap, noReportMetricIds)); } TEST(MetricsManagerTest, testAlertWithUnknownMetric) { UidMap uidMap; + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> periodicAlarmMonitor; StatsdConfig config = buildAlertWithUnknownMetric(); @@ -436,13 +429,11 @@ TEST(MetricsManagerTest, testAlertWithUnknownMetric) { unordered_map<int, std::vector<int>> trackerToConditionMap; std::set<int64_t> noReportMetricIds; - EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, - anomalyAlarmMonitor, periodicAlarmMonitor, - timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers, - allConditionTrackers, allMetricProducers, allAnomalyTrackers, - allAlarmTrackers, - conditionToMetricMap, trackerToMetricMap, trackerToConditionMap, - noReportMetricIds)); + EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, + periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds, + allAtomMatchers, allConditionTrackers, allMetricProducers, + allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, + trackerToMetricMap, trackerToConditionMap, noReportMetricIds)); } #else diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp index 76f3d8181dee..ecc57f5c4b26 100644 --- a/cmds/statsd/tests/StatsLogProcessor_test.cpp +++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp @@ -44,13 +44,13 @@ using android::util::ProtoOutputStream; */ class MockMetricsManager : public MetricsManager { public: - MockMetricsManager() : MetricsManager( - ConfigKey(1, 12345), StatsdConfig(), 1000, 1000, - new UidMap(), - new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t){}, - [](const sp<IStatsCompanionService>&){}), - new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t){}, - [](const sp<IStatsCompanionService>&){})) { + MockMetricsManager() + : MetricsManager(ConfigKey(1, 12345), StatsdConfig(), 1000, 1000, new UidMap(), + new StatsPullerManager(), + new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t) {}, + [](const sp<IStatsCompanionService>&) {}), + new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t) {}, + [](const sp<IStatsCompanionService>&) {})) { } MOCK_METHOD0(byteSize, size_t()); @@ -60,11 +60,12 @@ public: TEST(StatsLogProcessorTest, TestRateLimitByteSize) { sp<UidMap> m = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> periodicAlarmMonitor; // Construct the processor with a dummy sendBroadcast function that does nothing. - StatsLogProcessor p(m, anomalyAlarmMonitor, periodicAlarmMonitor, 0, - [](const ConfigKey& key) {return true;}); + StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, 0, + [](const ConfigKey& key) { return true; }); MockMetricsManager mockMetricsManager; @@ -79,11 +80,15 @@ TEST(StatsLogProcessorTest, TestRateLimitByteSize) { TEST(StatsLogProcessorTest, TestRateLimitBroadcast) { sp<UidMap> m = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> subscriberAlarmMonitor; int broadcastCount = 0; - StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, - [&broadcastCount](const ConfigKey& key) { broadcastCount++; return true;}); + StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, + [&broadcastCount](const ConfigKey& key) { + broadcastCount++; + return true; + }); MockMetricsManager mockMetricsManager; @@ -105,11 +110,15 @@ TEST(StatsLogProcessorTest, TestRateLimitBroadcast) { TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge) { sp<UidMap> m = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> subscriberAlarmMonitor; int broadcastCount = 0; - StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, - [&broadcastCount](const ConfigKey& key) { broadcastCount++; return true;}); + StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, + [&broadcastCount](const ConfigKey& key) { + broadcastCount++; + return true; + }); MockMetricsManager mockMetricsManager; @@ -143,12 +152,16 @@ StatsdConfig MakeConfig(bool includeMetric) { TEST(StatsLogProcessorTest, TestUidMapHasSnapshot) { // Setup simple config key corresponding to empty config. sp<UidMap> m = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); m->updateMap(1, {1, 2}, {1, 2}, {String16("p1"), String16("p2")}); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> subscriberAlarmMonitor; int broadcastCount = 0; - StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, - [&broadcastCount](const ConfigKey& key) { broadcastCount++; return true;}); + StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, + [&broadcastCount](const ConfigKey& key) { + broadcastCount++; + return true; + }); ConfigKey key(3, 4); StatsdConfig config = MakeConfig(true); p.OnConfigUpdated(0, key, config); @@ -168,12 +181,16 @@ TEST(StatsLogProcessorTest, TestUidMapHasSnapshot) { TEST(StatsLogProcessorTest, TestEmptyConfigHasNoUidMap) { // Setup simple config key corresponding to empty config. sp<UidMap> m = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); m->updateMap(1, {1, 2}, {1, 2}, {String16("p1"), String16("p2")}); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> subscriberAlarmMonitor; int broadcastCount = 0; - StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, - [&broadcastCount](const ConfigKey& key) { broadcastCount++; return true;}); + StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, + [&broadcastCount](const ConfigKey& key) { + broadcastCount++; + return true; + }); ConfigKey key(3, 4); StatsdConfig config = MakeConfig(false); p.OnConfigUpdated(0, key, config); @@ -191,11 +208,15 @@ TEST(StatsLogProcessorTest, TestEmptyConfigHasNoUidMap) { TEST(StatsLogProcessorTest, TestReportIncludesSubConfig) { // Setup simple config key corresponding to empty config. sp<UidMap> m = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> subscriberAlarmMonitor; int broadcastCount = 0; - StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, - [&broadcastCount](const ConfigKey& key) { broadcastCount++; return true;}); + StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, + [&broadcastCount](const ConfigKey& key) { + broadcastCount++; + return true; + }); ConfigKey key(3, 4); StatsdConfig config; auto annotation = config.add_annotation(); @@ -220,11 +241,15 @@ TEST(StatsLogProcessorTest, TestReportIncludesSubConfig) { TEST(StatsLogProcessorTest, TestOutOfOrderLogs) { // Setup simple config key corresponding to empty config. sp<UidMap> m = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> subscriberAlarmMonitor; int broadcastCount = 0; - StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, - [&broadcastCount](const ConfigKey& key) { broadcastCount++; return true;}); + StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, + [&broadcastCount](const ConfigKey& key) { + broadcastCount++; + return true; + }); LogEvent event1(0, 1 /*logd timestamp*/, 1001 /*elapsedRealtime*/); event1.init(); diff --git a/cmds/statsd/tests/UidMap_test.cpp b/cmds/statsd/tests/UidMap_test.cpp index e23131d7b45d..99082cc647f6 100644 --- a/cmds/statsd/tests/UidMap_test.cpp +++ b/cmds/statsd/tests/UidMap_test.cpp @@ -40,11 +40,12 @@ const string kApp2 = "app2.sharing.1"; TEST(UidMapTest, TestIsolatedUID) { sp<UidMap> m = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); sp<AlarmMonitor> anomalyAlarmMonitor; sp<AlarmMonitor> subscriberAlarmMonitor; // Construct the processor with a dummy sendBroadcast function that does nothing. - StatsLogProcessor p(m, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, - [](const ConfigKey& key) {return true;}); + StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, + [](const ConfigKey& key) { return true; }); LogEvent addEvent(android::util::ISOLATED_UID_CHANGED, 1); addEvent.write(100); // parent UID addEvent.write(101); // isolated UID diff --git a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp index 218d52a5c046..79bed52f0202 100644 --- a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp +++ b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp @@ -305,10 +305,10 @@ TEST(AnomalyTrackerTest, TestSparseBuckets) { EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL); EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL); EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 16, bucket16, {keyB}, {keyA, keyC, keyD})); - // TODO: after detectAnomaly fix: EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL); + EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL); EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 15L); detectAndDeclareAnomalies(anomalyTracker, 16, bucket16, eventTimestamp2); - // TODO: after detectAnomaly fix: EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL); + EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL); EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 15L); checkRefractoryTimes(anomalyTracker, eventTimestamp2, refractoryPeriodSec, {{keyA, -1}, {keyB, eventTimestamp2}, {keyC, -1}, {keyD, -1}, {keyE, -1}}); @@ -366,7 +366,7 @@ TEST(AnomalyTrackerTest, TestSparseBuckets) { EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL); EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 25, bucket25, {}, {keyA, keyB, keyC, keyD})); EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 24L); - // TODO: after detectAnomaly fix: EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL); + EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL); detectAndDeclareAnomalies(anomalyTracker, 25, bucket25, eventTimestamp5); checkRefractoryTimes(anomalyTracker, eventTimestamp5, refractoryPeriodSec, {{keyA, -1}, {keyB, eventTimestamp4}, {keyC, -1}, {keyD, -1}, {keyE, -1}}); @@ -374,14 +374,14 @@ TEST(AnomalyTrackerTest, TestSparseBuckets) { // Add past bucket #25 anomalyTracker.addPastBucket(bucket25, 25); EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 25L); - // TODO: after detectAnomaly fix: EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL); + EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL); EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyD), 1LL); EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 28, bucket28, {}, {keyA, keyB, keyC, keyD, keyE})); EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 27L); - // TODO: after detectAnomaly fix: EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL); + EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL); detectAndDeclareAnomalies(anomalyTracker, 28, bucket28, eventTimestamp6); - // TODO: after detectAnomaly fix: EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL); + EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL); checkRefractoryTimes(anomalyTracker, eventTimestamp6, refractoryPeriodSec, {{keyA, -1}, {keyB, -1}, {keyC, -1}, {keyD, -1}, {keyE, -1}}); @@ -390,9 +390,9 @@ TEST(AnomalyTrackerTest, TestSparseBuckets) { EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 28, bucket28, {keyE}, {keyA, keyB, keyC, keyD})); EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 27L); - // TODO: after detectAnomaly fix: EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL); + EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL); detectAndDeclareAnomalies(anomalyTracker, 28, bucket28, eventTimestamp6 + 7); - // TODO: after detectAnomaly fix: EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL); + EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL); checkRefractoryTimes(anomalyTracker, eventTimestamp6, refractoryPeriodSec, {{keyA, -1}, {keyB, -1}, {keyC, -1}, {keyD, -1}, {keyE, eventTimestamp6 + 7}}); } diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp index eca5690de478..d98395e78467 100644 --- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp +++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp @@ -66,7 +66,7 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents) { baseTimeNs, configAddedTimeNs, config, cfgKey); EXPECT_EQ(processor->mMetricsManagers.size(), 1u); EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); - processor->mStatsPullerManager.ForceClearPullerCache(); + processor->mPullerManager->ForceClearPullerCache(); int startBucketNum = processor->mMetricsManagers.begin()->second-> mAllMetricProducers[0]->getCurrentBucketNum(); @@ -74,12 +74,11 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents) { // When creating the config, the gauge metric producer should register the alarm at the // end of the current bucket. - EXPECT_EQ((size_t)1, StatsPullerManagerImpl::GetInstance().mReceivers.size()); + EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size()); EXPECT_EQ(bucketSizeNs, - StatsPullerManagerImpl::GetInstance().mReceivers.begin()-> - second.front().intervalNs); - int64_t& nextPullTimeNs = StatsPullerManagerImpl::GetInstance().mReceivers.begin()-> - second.front().nextPullTimeNs; + processor->mPullerManager->mReceivers.begin()->second.front().intervalNs); + int64_t& nextPullTimeNs = + processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs; EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs); auto screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, @@ -212,7 +211,7 @@ TEST(GaugeMetricE2eTest, TestAllConditionChangesSamplePulledEvents) { baseTimeNs, configAddedTimeNs, config, cfgKey); EXPECT_EQ(processor->mMetricsManagers.size(), 1u); EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); - processor->mStatsPullerManager.ForceClearPullerCache(); + processor->mPullerManager->ForceClearPullerCache(); int startBucketNum = processor->mMetricsManagers.begin()->second-> mAllMetricProducers[0]->getCurrentBucketNum(); @@ -313,7 +312,7 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm) { baseTimeNs, configAddedTimeNs, config, cfgKey); EXPECT_EQ(processor->mMetricsManagers.size(), 1u); EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); - processor->mStatsPullerManager.ForceClearPullerCache(); + processor->mPullerManager->ForceClearPullerCache(); int startBucketNum = processor->mMetricsManagers.begin()->second-> mAllMetricProducers[0]->getCurrentBucketNum(); @@ -321,12 +320,11 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm) { // When creating the config, the gauge metric producer should register the alarm at the // end of the current bucket. - EXPECT_EQ((size_t)1, StatsPullerManagerImpl::GetInstance().mReceivers.size()); + EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size()); EXPECT_EQ(bucketSizeNs, - StatsPullerManagerImpl::GetInstance().mReceivers.begin()-> - second.front().intervalNs); - int64_t& nextPullTimeNs = StatsPullerManagerImpl::GetInstance().mReceivers.begin()-> - second.front().nextPullTimeNs; + processor->mPullerManager->mReceivers.begin()->second.front().intervalNs); + int64_t& nextPullTimeNs = + processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs; EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, nextPullTimeNs); auto screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, diff --git a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp index 11aaab00d88c..cc8894bdbca6 100644 --- a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp @@ -99,7 +99,6 @@ StatsdConfig CreateStatsdConfig() { // If we want to test multiple dump data, we must do it in separate tests, because in the e2e tests, // we should use the real API which will clear the data after dump data is called. -// TODO: better refactor the code so that the tests are not so verbose. TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1) { auto config = CreateStatsdConfig(); uint64_t bucketStartTimeNs = 10000000000; diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp index dd28d3611b4f..744828e990f1 100644 --- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp +++ b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp @@ -66,7 +66,7 @@ TEST(ValueMetricE2eTest, TestPulledEvents) { baseTimeNs, configAddedTimeNs, config, cfgKey); EXPECT_EQ(processor->mMetricsManagers.size(), 1u); EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); - processor->mStatsPullerManager.ForceClearPullerCache(); + processor->mPullerManager->ForceClearPullerCache(); int startBucketNum = processor->mMetricsManagers.begin()->second-> mAllMetricProducers[0]->getCurrentBucketNum(); @@ -74,12 +74,11 @@ TEST(ValueMetricE2eTest, TestPulledEvents) { // When creating the config, the gauge metric producer should register the alarm at the // end of the current bucket. - EXPECT_EQ((size_t)1, StatsPullerManagerImpl::GetInstance().mReceivers.size()); + EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size()); EXPECT_EQ(bucketSizeNs, - StatsPullerManagerImpl::GetInstance().mReceivers.begin()-> - second.front().intervalNs); - int64_t& expectedPullTimeNs = StatsPullerManagerImpl::GetInstance().mReceivers.begin()-> - second.front().nextPullTimeNs; + processor->mPullerManager->mReceivers.begin()->second.front().intervalNs); + int64_t& expectedPullTimeNs = + processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs; EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs); auto screenOffEvent = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_OFF, @@ -173,7 +172,7 @@ TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm) { baseTimeNs, configAddedTimeNs, config, cfgKey); EXPECT_EQ(processor->mMetricsManagers.size(), 1u); EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid()); - processor->mStatsPullerManager.ForceClearPullerCache(); + processor->mPullerManager->ForceClearPullerCache(); int startBucketNum = processor->mMetricsManagers.begin()->second-> mAllMetricProducers[0]->getCurrentBucketNum(); @@ -181,12 +180,11 @@ TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm) { // When creating the config, the gauge metric producer should register the alarm at the // end of the current bucket. - EXPECT_EQ((size_t)1, StatsPullerManagerImpl::GetInstance().mReceivers.size()); + EXPECT_EQ((size_t)1, processor->mPullerManager->mReceivers.size()); EXPECT_EQ(bucketSizeNs, - StatsPullerManagerImpl::GetInstance().mReceivers.begin()-> - second.front().intervalNs); - int64_t& expectedPullTimeNs = StatsPullerManagerImpl::GetInstance().mReceivers.begin()-> - second.front().nextPullTimeNs; + processor->mPullerManager->mReceivers.begin()->second.front().intervalNs); + int64_t& expectedPullTimeNs = + processor->mPullerManager->mReceivers.begin()->second.front().nextPullTimeNs; EXPECT_EQ(baseTimeNs + startBucketNum * bucketSizeNs + bucketSizeNs, expectedPullTimeNs); // Screen off/on/off events. diff --git a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp index 3a1546641d45..d2fd95c818cf 100644 --- a/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/EventMetricProducer_test.cpp @@ -54,8 +54,8 @@ TEST(EventMetricProducerTest, TestNoCondition) { eventProducer.onMatchedLogEvent(1 /*matcher index*/, event1); eventProducer.onMatchedLogEvent(1 /*matcher index*/, event2); - // TODO: get the report and check the content after the ProtoOutputStream change is done. - // eventProducer.onDumpReport(); + // TODO(b/110561136): get the report and check the content after the ProtoOutputStream change + // is done eventProducer.onDumpReport(); } TEST(EventMetricProducerTest, TestEventsWithNonSlicedCondition) { diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp index 698ce727e688..19c9f775465b 100644 --- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp @@ -59,10 +59,7 @@ TEST(GaugeMetricProducerTest, TestNoCondition) { sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - // TODO: pending refactor of StatsPullerManager - // For now we still need this so that it doesn't do real pulling. - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); @@ -89,8 +86,7 @@ TEST(GaugeMetricProducerTest, TestNoCondition) { EXPECT_EQ(0UL, gaugeProducer.mPastBuckets.size()); allData.clear(); - std::shared_ptr<LogEvent> event2 = - std::make_shared<LogEvent>(tagId, bucket3StartTimeNs + 10); + std::shared_ptr<LogEvent> event2 = std::make_shared<LogEvent>(tagId, bucket3StartTimeNs + 10); event2->write(24); event2->write("some value"); event2->write(25); @@ -140,8 +136,7 @@ TEST(GaugeMetricProducerTest, TestPushedEventsWithUpgrade) { alert.set_trigger_if_sum_gt(25); alert.set_num_buckets(100); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, -1 /* -1 means no pulling */, bucketStartTimeNs, bucketStartTimeNs, pullerManager); @@ -211,8 +206,7 @@ TEST(GaugeMetricProducerTest, TestPulledWithUpgrade) { sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) @@ -280,8 +274,7 @@ TEST(GaugeMetricProducerTest, TestWithCondition) { sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) @@ -296,8 +289,8 @@ TEST(GaugeMetricProducerTest, TestWithCondition) { return true; })); - GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard, tagId, - bucketStartTimeNs, bucketStartTimeNs, pullerManager); + GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs, + bucketStartTimeNs, pullerManager); gaugeProducer.setBucketSize(60 * NS_PER_SEC); gaugeProducer.onConditionChanged(true, bucketStartTimeNs + 8); @@ -372,8 +365,7 @@ TEST(GaugeMetricProducerTest, TestWithSlicedCondition) { return ConditionState::kTrue; })); - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) @@ -421,8 +413,7 @@ TEST(GaugeMetricProducerTest, TestAnomalyDetection) { sp<AlarmMonitor> alarmMonitor; sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); @@ -472,7 +463,7 @@ TEST(GaugeMetricProducerTest, TestAnomalyDetection) { .mFields->begin() ->mValue.int_value); EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), - std::ceil(1.0 * event2->GetElapsedTimestampNs() / NS_PER_SEC) + refPeriodSec); + std::ceil(1.0 * event2->GetElapsedTimestampNs() / NS_PER_SEC) + refPeriodSec); std::shared_ptr<LogEvent> event3 = std::make_shared<LogEvent>(tagId, bucketStartTimeNs + 2 * bucketSizeNs + 10); @@ -487,7 +478,7 @@ TEST(GaugeMetricProducerTest, TestAnomalyDetection) { .mFields->begin() ->mValue.int_value); EXPECT_EQ(anomalyTracker->getRefractoryPeriodEndsSec(DEFAULT_METRIC_DIMENSION_KEY), - std::ceil(1.0 * event2->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec)); + std::ceil(1.0 * event2->GetElapsedTimestampNs() / NS_PER_SEC + refPeriodSec)); // The event4 does not have the gauge field. Thus the current bucket value is 0. std::shared_ptr<LogEvent> event4 = diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp index e3a8a553acc9..5195f018e76d 100644 --- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp +++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp @@ -60,10 +60,7 @@ TEST(ValueMetricProducerTest, TestNonDimensionalEvents) { metric.mutable_value_field()->add_child()->set_field(2); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - // TODO: pending refactor of StatsPullerManager - // For now we still need this so that it doesn't do real pulling. - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); @@ -140,8 +137,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) { metric.set_use_absolute_value_on_reset(true); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); @@ -214,8 +210,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) { metric.mutable_value_field()->add_child()->set_field(2); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); @@ -287,8 +282,7 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) { metric.set_condition(StringToId("SCREEN_ON")); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); @@ -365,8 +359,7 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade) { metric.mutable_value_field()->add_child()->set_field(2); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, -1, bucketStartTimeNs, bucketStartTimeNs, pullerManager); valueProducer.setBucketSize(60 * NS_PER_SEC); @@ -408,8 +401,7 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) { metric.mutable_value_field()->add_child()->set_field(2); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) @@ -464,8 +456,7 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) { metric.set_condition(StringToId("SCREEN_ON")); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, Pull(tagId, _, _)) @@ -514,8 +505,7 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) { metric.mutable_value_field()->add_child()->set_field(2); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, -1, bucketStartTimeNs, bucketStartTimeNs, pullerManager); @@ -556,8 +546,7 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) { metric.mutable_value_field()->add_child()->set_field(2); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, -1, bucketStartTimeNs, bucketStartTimeNs, pullerManager); @@ -631,8 +620,10 @@ TEST(ValueMetricProducerTest, TestAnomalyDetection) { metric.mutable_value_field()->add_child()->set_field(2); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard, - -1 /*not pulled*/, bucketStartTimeNs, bucketStartTimeNs); + -1 /*not pulled*/, bucketStartTimeNs, bucketStartTimeNs, + pullerManager); valueProducer.setBucketSize(60 * NS_PER_SEC); sp<AnomalyTracker> anomalyTracker = valueProducer.addAnomalyTracker(alert, alarmMonitor); @@ -705,8 +696,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) { metric.mutable_value_field()->add_child()->set_field(2); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return()); @@ -790,8 +780,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) { metric.set_condition(StringToId("SCREEN_ON")); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); @@ -873,8 +862,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) { metric.set_condition(StringToId("SCREEN_ON")); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillRepeatedly(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); @@ -976,8 +964,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition3) { metric.set_condition(StringToId("SCREEN_ON")); sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>(); - shared_ptr<MockStatsPullerManager> pullerManager = - make_shared<StrictMock<MockStatsPullerManager>>(); + sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>(); EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return()); EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return()); diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp index e0c98cb9735b..b8b1a1db2c12 100644 --- a/cmds/statsd/tests/statsd_test_util.cpp +++ b/cmds/statsd/tests/statsd_test_util.cpp @@ -452,14 +452,16 @@ std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent( sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs, const StatsdConfig& config, const ConfigKey& key) { sp<UidMap> uidMap = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); sp<AlarmMonitor> anomalyAlarmMonitor = new AlarmMonitor(1, [](const sp<IStatsCompanionService>&, int64_t){}, [](const sp<IStatsCompanionService>&){}); sp<AlarmMonitor> periodicAlarmMonitor = new AlarmMonitor(1, [](const sp<IStatsCompanionService>&, int64_t){}, [](const sp<IStatsCompanionService>&){}); - sp<StatsLogProcessor> processor = new StatsLogProcessor( - uidMap, anomalyAlarmMonitor, periodicAlarmMonitor, timeBaseNs, [](const ConfigKey&){return true;}); + sp<StatsLogProcessor> processor = + new StatsLogProcessor(uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor, + timeBaseNs, [](const ConfigKey&) { return true; }); processor->OnConfigUpdated(currentTimeNs, key, config); return processor; } diff --git a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java index 653851546d01..950a258d123d 100644 --- a/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java +++ b/cmds/uiautomator/library/testrunner-src/com/android/uiautomator/core/ShellUiAutomatorBridge.java @@ -62,7 +62,7 @@ public class ShellUiAutomatorBridge extends UiAutomatorBridge { IBinder token = new Binder(); try { ContentProviderHolder holder = activityManager.getContentProviderExternal( - providerName, UserHandle.USER_SYSTEM, token); + providerName, UserHandle.USER_SYSTEM, token, "*uiautomator*"); if (holder == null) { throw new IllegalStateException("Could not find provider: " + providerName); } |