Yi Kong | e5576ae | 2020-08-05 02:00:05 +0800 | [diff] [blame] | 1 | // |
| 2 | // Copyright (C) 2020 The Android Open Source Project |
| 3 | // |
| 4 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | // you may not use this file except in compliance with the License. |
| 6 | // You may obtain a copy of the License at |
| 7 | // |
| 8 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | // |
| 10 | // Unless required by applicable law or agreed to in writing, software |
| 11 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | // See the License for the specific language governing permissions and |
| 14 | // limitations under the License. |
| 15 | // |
| 16 | |
Yi Kong | 80f579d | 2020-11-09 20:40:01 +0800 | [diff] [blame] | 17 | //! ProfCollect Binder client interface. |
| 18 | |
Yi Kong | e3aab14 | 2021-03-02 13:58:25 +0800 | [diff] [blame] | 19 | mod config; |
| 20 | mod report; |
| 21 | mod scheduler; |
| 22 | mod service; |
| 23 | mod simpleperf_etm_trace_provider; |
| 24 | mod trace_provider; |
| 25 | |
Yi Kong | 8c59b8f | 2021-06-18 16:28:54 -0700 | [diff] [blame] | 26 | #[cfg(feature = "test")] |
| 27 | mod logging_trace_provider; |
| 28 | |
Yi Kong | c6d5ff1 | 2021-03-10 02:20:45 +0800 | [diff] [blame] | 29 | use anyhow::{Context, Result}; |
Yi Kong | e3aab14 | 2021-03-02 13:58:25 +0800 | [diff] [blame] | 30 | use profcollectd_aidl_interface::aidl::com::android::server::profcollect::IProfCollectd::{ |
| 31 | self, BnProfCollectd, |
| 32 | }; |
Yabin Cui | f158a75 | 2022-01-10 15:35:59 -0800 | [diff] [blame] | 33 | use profcollectd_aidl_interface::aidl::com::android::server::profcollect::IProviderStatusCallback::{IProviderStatusCallback, BnProviderStatusCallback}; |
Andrew Walbran | 064c365 | 2021-04-14 13:53:09 +0000 | [diff] [blame] | 34 | use profcollectd_aidl_interface::binder::{self, BinderFeatures}; |
Yabin Cui | f158a75 | 2022-01-10 15:35:59 -0800 | [diff] [blame] | 35 | use service::{err_to_binder_status, ProfcollectdBinderService}; |
| 36 | use std::time::{Duration, Instant}; |
Yi Kong | e3aab14 | 2021-03-02 13:58:25 +0800 | [diff] [blame] | 37 | |
| 38 | const PROFCOLLECTD_SERVICE_NAME: &str = "profcollectd"; |
Yi Kong | e5576ae | 2020-08-05 02:00:05 +0800 | [diff] [blame] | 39 | |
Yabin Cui | f158a75 | 2022-01-10 15:35:59 -0800 | [diff] [blame] | 40 | struct ProviderStatusCallback { |
| 41 | service_start_time: Instant, |
| 42 | } |
| 43 | |
| 44 | impl binder::Interface for ProviderStatusCallback {} |
| 45 | |
| 46 | impl IProviderStatusCallback for ProviderStatusCallback { |
| 47 | fn onProviderReady(&self) -> binder::Result<()> { |
| 48 | // If we have waited too long for the provider to be ready, then we have passed |
| 49 | // boot phase, and no need to collect boot profile. |
| 50 | // TODO: should we check boottime instead? |
| 51 | const TIMEOUT_TO_COLLECT_BOOT_PROFILE: Duration = Duration::from_secs(3); |
| 52 | let elapsed = Instant::now().duration_since(self.service_start_time); |
| 53 | if elapsed < TIMEOUT_TO_COLLECT_BOOT_PROFILE { |
| 54 | trace_once("boot").map_err(err_to_binder_status)?; |
| 55 | } |
| 56 | schedule().map_err(err_to_binder_status)?; |
| 57 | Ok(()) |
| 58 | } |
| 59 | } |
| 60 | |
Yi Kong | e5576ae | 2020-08-05 02:00:05 +0800 | [diff] [blame] | 61 | /// Initialise profcollectd service. |
Yi Kong | e3aab14 | 2021-03-02 13:58:25 +0800 | [diff] [blame] | 62 | /// * `schedule_now` - Immediately schedule collection after service is initialised. |
| 63 | pub fn init_service(schedule_now: bool) -> Result<()> { |
| 64 | binder::ProcessState::start_thread_pool(); |
| 65 | |
| 66 | let profcollect_binder_service = ProfcollectdBinderService::new()?; |
| 67 | binder::add_service( |
Chris Wailes | 8f571e1 | 2021-07-27 16:04:09 -0700 | [diff] [blame] | 68 | PROFCOLLECTD_SERVICE_NAME, |
Andrew Walbran | 064c365 | 2021-04-14 13:53:09 +0000 | [diff] [blame] | 69 | BnProfCollectd::new_binder(profcollect_binder_service, BinderFeatures::default()) |
| 70 | .as_binder(), |
Yi Kong | e3aab14 | 2021-03-02 13:58:25 +0800 | [diff] [blame] | 71 | ) |
| 72 | .context("Failed to register service.")?; |
| 73 | |
| 74 | if schedule_now { |
Yabin Cui | f158a75 | 2022-01-10 15:35:59 -0800 | [diff] [blame] | 75 | let cb = BnProviderStatusCallback::new_binder( |
| 76 | ProviderStatusCallback { service_start_time: Instant::now() }, |
| 77 | BinderFeatures::default(), |
| 78 | ); |
| 79 | get_profcollectd_service()?.registerProviderStatusCallback(&cb)?; |
Yi Kong | e5576ae | 2020-08-05 02:00:05 +0800 | [diff] [blame] | 80 | } |
Yi Kong | e3aab14 | 2021-03-02 13:58:25 +0800 | [diff] [blame] | 81 | |
| 82 | binder::ProcessState::join_thread_pool(); |
| 83 | Ok(()) |
Yi Kong | e5576ae | 2020-08-05 02:00:05 +0800 | [diff] [blame] | 84 | } |
| 85 | |
Yi Kong | 74071ea | 2021-04-10 16:28:30 +0800 | [diff] [blame] | 86 | fn get_profcollectd_service() -> Result<binder::Strong<dyn IProfCollectd::IProfCollectd>> { |
Chris Wailes | 8f571e1 | 2021-07-27 16:04:09 -0700 | [diff] [blame] | 87 | binder::get_interface(PROFCOLLECTD_SERVICE_NAME) |
Yi Kong | 74071ea | 2021-04-10 16:28:30 +0800 | [diff] [blame] | 88 | .context("Failed to get profcollectd binder service, is profcollectd running?") |
Yi Kong | e3aab14 | 2021-03-02 13:58:25 +0800 | [diff] [blame] | 89 | } |
| 90 | |
Yi Kong | e5576ae | 2020-08-05 02:00:05 +0800 | [diff] [blame] | 91 | /// Schedule periodic profile collection. |
Yi Kong | e3aab14 | 2021-03-02 13:58:25 +0800 | [diff] [blame] | 92 | pub fn schedule() -> Result<()> { |
Yi Kong | 74071ea | 2021-04-10 16:28:30 +0800 | [diff] [blame] | 93 | get_profcollectd_service()?.schedule()?; |
Yi Kong | c6d5ff1 | 2021-03-10 02:20:45 +0800 | [diff] [blame] | 94 | Ok(()) |
Yi Kong | e5576ae | 2020-08-05 02:00:05 +0800 | [diff] [blame] | 95 | } |
| 96 | |
| 97 | /// Terminate periodic profile collection. |
Yi Kong | e3aab14 | 2021-03-02 13:58:25 +0800 | [diff] [blame] | 98 | pub fn terminate() -> Result<()> { |
Yi Kong | 74071ea | 2021-04-10 16:28:30 +0800 | [diff] [blame] | 99 | get_profcollectd_service()?.terminate()?; |
Yi Kong | c6d5ff1 | 2021-03-10 02:20:45 +0800 | [diff] [blame] | 100 | Ok(()) |
Yi Kong | e5576ae | 2020-08-05 02:00:05 +0800 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | /// Immediately schedule a one-off trace. |
Yi Kong | e3aab14 | 2021-03-02 13:58:25 +0800 | [diff] [blame] | 104 | pub fn trace_once(tag: &str) -> Result<()> { |
Yi Kong | 74071ea | 2021-04-10 16:28:30 +0800 | [diff] [blame] | 105 | get_profcollectd_service()?.trace_once(tag)?; |
Yi Kong | c6d5ff1 | 2021-03-10 02:20:45 +0800 | [diff] [blame] | 106 | Ok(()) |
Yi Kong | e5576ae | 2020-08-05 02:00:05 +0800 | [diff] [blame] | 107 | } |
| 108 | |
Yi Kong | e3aab14 | 2021-03-02 13:58:25 +0800 | [diff] [blame] | 109 | /// Process traces. |
| 110 | pub fn process() -> Result<()> { |
Yi Kong | e762742 | 2021-11-15 16:20:02 +0800 | [diff] [blame] | 111 | get_profcollectd_service()?.process()?; |
Yi Kong | c6d5ff1 | 2021-03-10 02:20:45 +0800 | [diff] [blame] | 112 | Ok(()) |
Yi Kong | e5576ae | 2020-08-05 02:00:05 +0800 | [diff] [blame] | 113 | } |
| 114 | |
Yi Kong | e3aab14 | 2021-03-02 13:58:25 +0800 | [diff] [blame] | 115 | /// Process traces and report profile. |
Yi Kong | 037bde8 | 2021-03-23 14:25:38 +0800 | [diff] [blame] | 116 | pub fn report() -> Result<String> { |
Yabin Cui | 1a2601f | 2023-05-11 14:28:57 -0700 | [diff] [blame] | 117 | Ok(get_profcollectd_service()?.report(report::NO_USAGE_SETTING)?) |
Yi Kong | 4e25de7 | 2020-09-08 14:43:33 +0800 | [diff] [blame] | 118 | } |
| 119 | |
Yi Kong | 34ebf87 | 2021-11-29 19:57:55 +0800 | [diff] [blame] | 120 | /// Clear all local data. |
| 121 | pub fn reset() -> Result<()> { |
| 122 | config::clear_data()?; |
| 123 | Ok(()) |
| 124 | } |
| 125 | |
Yi Kong | e3aab14 | 2021-03-02 13:58:25 +0800 | [diff] [blame] | 126 | /// Inits logging for Android |
| 127 | pub fn init_logging() { |
Yi Kong | 8c59b8f | 2021-06-18 16:28:54 -0700 | [diff] [blame] | 128 | let min_log_level = if cfg!(feature = "test") { log::Level::Info } else { log::Level::Error }; |
Yi Kong | e3aab14 | 2021-03-02 13:58:25 +0800 | [diff] [blame] | 129 | android_logger::init_once( |
Yi Kong | d1cca10 | 2022-02-23 21:26:09 +0800 | [diff] [blame] | 130 | android_logger::Config::default() |
| 131 | .with_tag("profcollectd") |
| 132 | .with_min_level(min_log_level) |
| 133 | .with_log_id(android_logger::LogId::System), |
Yi Kong | e3aab14 | 2021-03-02 13:58:25 +0800 | [diff] [blame] | 134 | ); |
Yi Kong | e5576ae | 2020-08-05 02:00:05 +0800 | [diff] [blame] | 135 | } |