| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef _STORAGED_H_ |
| #define _STORAGED_H_ |
| |
| #include <semaphore.h> |
| #include <stdint.h> |
| #include <time.h> |
| |
| #include <queue> |
| #include <string> |
| #include <unordered_map> |
| #include <vector> |
| |
| #include <utils/Mutex.h> |
| |
| #include <aidl/android/hardware/health/IHealth.h> |
| #include <android/hardware/health/2.0/IHealth.h> |
| |
| #define FRIEND_TEST(test_case_name, test_name) \ |
| friend class test_case_name##_##test_name##_Test |
| |
| #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) |
| |
| #define IS_ALIGNED(x, align) (!((x) & ((align) - 1))) |
| #define ROUND_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1)) |
| |
| #define SECTOR_SIZE ( 512 ) |
| #define SEC_TO_MSEC ( 1000 ) |
| #define MSEC_TO_USEC ( 1000 ) |
| #define USEC_TO_NSEC ( 1000 ) |
| #define SEC_TO_USEC ( 1000000 ) |
| #define HOUR_TO_SEC ( 3600 ) |
| #define DAY_TO_SEC ( 3600 * 24 ) |
| #define WEEK_TO_DAYS ( 7 ) |
| #define YEAR_TO_WEEKS ( 52 ) |
| |
| #include "storaged_diskstats.h" |
| #include "storaged_info.h" |
| #include "storaged_uid_monitor.h" |
| #include "storaged.pb.h" |
| #include "uid_info.h" |
| |
| using namespace std; |
| using namespace android; |
| |
| // Periodic chores intervals in seconds |
| #define DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT ( 60 ) |
| #define DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH ( 3600 ) |
| #define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO ( 3600 ) |
| #define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO_LIMIT ( 300 ) |
| #define DEFAULT_PERIODIC_CHORES_INTERVAL_FLUSH_PROTO ( 3600 ) |
| |
| // UID IO threshold in bytes |
| #define DEFAULT_PERIODIC_CHORES_UID_IO_THRESHOLD ( 1024 * 1024 * 1024ULL ) |
| |
| class storaged_t; |
| |
| struct storaged_config { |
| int periodic_chores_interval_unit; |
| int periodic_chores_interval_disk_stats_publish; |
| int periodic_chores_interval_uid_io; |
| int periodic_chores_interval_flush_proto; |
| int event_time_check_usec; // check how much cputime spent in event loop |
| }; |
| |
| struct HealthServicePair { |
| std::shared_ptr<aidl::android::hardware::health::IHealth> aidl_health; |
| android::sp<android::hardware::health::V2_0::IHealth> hidl_health; |
| static HealthServicePair get(); |
| }; |
| |
| class hidl_health_death_recipient : public android::hardware::hidl_death_recipient { |
| public: |
| hidl_health_death_recipient(const android::sp<android::hardware::health::V2_0::IHealth>& health) |
| : mHealth(health) {} |
| void serviceDied(uint64_t cookie, const wp<::android::hidl::base::V1_0::IBase>& who); |
| |
| private: |
| android::sp<android::hardware::health::V2_0::IHealth> mHealth; |
| }; |
| |
| class storaged_t : public RefBase { |
| private: |
| time_t mTimer; |
| storaged_config mConfig; |
| unique_ptr<disk_stats_monitor> mDsm; |
| uid_monitor mUidm; |
| time_t mStarttime; |
| std::shared_ptr<aidl::android::hardware::health::IHealth> health; |
| sp<android::hardware::hidl_death_recipient> hidl_death_recp; |
| ndk::ScopedAIBinder_DeathRecipient aidl_death_recp; |
| shared_ptr<aidl::android::hardware::health::IHealthInfoCallback> aidl_health_callback; |
| unique_ptr<storage_info_t> storage_info; |
| static const uint32_t current_version; |
| Mutex proto_lock; |
| unordered_map<userid_t, bool> proto_loaded; |
| void load_proto(userid_t user_id); |
| char* prepare_proto(userid_t user_id, StoragedProto* proto); |
| void flush_proto(userid_t user_id, StoragedProto* proto); |
| void flush_proto_data(userid_t user_id, const char* data, ssize_t size); |
| string proto_path(userid_t user_id) { |
| return string("/data/misc_ce/") + to_string(user_id) + |
| "/storaged/storaged.proto"; |
| } |
| void init_health_service(); |
| |
| public: |
| storaged_t(void); |
| void init(void); |
| void event(void); |
| void event_checked(void); |
| void pause(void) { |
| sleep(mConfig.periodic_chores_interval_unit); |
| } |
| |
| time_t get_starttime(void) { |
| return mStarttime; |
| } |
| |
| unordered_map<uint32_t, uid_info> get_uids(void) { |
| return mUidm.get_uid_io_stats(); |
| } |
| |
| vector<int> get_perf_history(void) { |
| return storage_info->get_perf_history(); |
| } |
| |
| uint32_t get_recent_perf(void) { return storage_info->get_recent_perf(); } |
| |
| map<uint64_t, struct uid_records> get_uid_records( |
| double hours, uint64_t threshold, bool force_report) { |
| return mUidm.dump(hours, threshold, force_report); |
| } |
| |
| void update_uid_io_interval(int interval) { |
| if (interval >= DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO_LIMIT) { |
| mConfig.periodic_chores_interval_uid_io = interval; |
| } |
| } |
| |
| void add_user_ce(userid_t user_id); |
| void remove_user_ce(userid_t user_id); |
| |
| void report_storage_info(); |
| |
| void flush_protos(unordered_map<int, StoragedProto>* protos); |
| }; |
| |
| // Eventlog tag |
| // The content must match the definition in EventLogTags.logtags |
| #define EVENTLOGTAG_DISKSTATS ( 2732 ) |
| #define EVENTLOGTAG_EMMCINFO ( 2733 ) |
| #define EVENTLOGTAG_UID_IO_ALERT ( 2734 ) |
| |
| #endif /* _STORAGED_H_ */ |