blob: 87ce50b6ce552cf52905e7e0361deff1ad60a8a4 [file] [log] [blame]
Yi Konge5576ae2020-08-05 02:00:05 +08001//
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 Kong80f579d2020-11-09 20:40:01 +080017//! ProfCollect Binder client interface.
18
Yi Konge3aab142021-03-02 13:58:25 +080019mod config;
20mod report;
21mod scheduler;
22mod service;
23mod simpleperf_etm_trace_provider;
Yabin Cuiffc25f82023-12-13 11:04:40 -080024mod simpleperf_lbr_trace_provider;
Yi Konge3aab142021-03-02 13:58:25 +080025mod trace_provider;
26
Yi Kong8c59b8f2021-06-18 16:28:54 -070027#[cfg(feature = "test")]
28mod logging_trace_provider;
29
Yi Kongc6d5ff12021-03-10 02:20:45 +080030use anyhow::{Context, Result};
Yi Konge3aab142021-03-02 13:58:25 +080031use profcollectd_aidl_interface::aidl::com::android::server::profcollect::IProfCollectd::{
32 self, BnProfCollectd,
33};
Yabin Cuif158a752022-01-10 15:35:59 -080034use profcollectd_aidl_interface::aidl::com::android::server::profcollect::IProviderStatusCallback::{IProviderStatusCallback, BnProviderStatusCallback};
Andrew Walbran064c3652021-04-14 13:53:09 +000035use profcollectd_aidl_interface::binder::{self, BinderFeatures};
Yabin Cuif158a752022-01-10 15:35:59 -080036use service::{err_to_binder_status, ProfcollectdBinderService};
37use std::time::{Duration, Instant};
Yi Konge3aab142021-03-02 13:58:25 +080038
39const PROFCOLLECTD_SERVICE_NAME: &str = "profcollectd";
Yi Konge5576ae2020-08-05 02:00:05 +080040
Yabin Cuif158a752022-01-10 15:35:59 -080041struct ProviderStatusCallback {
42 service_start_time: Instant,
43}
44
45impl binder::Interface for ProviderStatusCallback {}
46
47impl IProviderStatusCallback for ProviderStatusCallback {
48 fn onProviderReady(&self) -> binder::Result<()> {
49 // If we have waited too long for the provider to be ready, then we have passed
50 // boot phase, and no need to collect boot profile.
51 // TODO: should we check boottime instead?
52 const TIMEOUT_TO_COLLECT_BOOT_PROFILE: Duration = Duration::from_secs(3);
53 let elapsed = Instant::now().duration_since(self.service_start_time);
54 if elapsed < TIMEOUT_TO_COLLECT_BOOT_PROFILE {
Yi Kongc26c15b2024-07-06 17:20:44 +090055 trace_system("boot").map_err(err_to_binder_status)?;
Yabin Cuif158a752022-01-10 15:35:59 -080056 }
57 schedule().map_err(err_to_binder_status)?;
58 Ok(())
59 }
60}
61
Yi Konge5576ae2020-08-05 02:00:05 +080062/// Initialise profcollectd service.
Yi Konge3aab142021-03-02 13:58:25 +080063/// * `schedule_now` - Immediately schedule collection after service is initialised.
64pub fn init_service(schedule_now: bool) -> Result<()> {
65 binder::ProcessState::start_thread_pool();
66
67 let profcollect_binder_service = ProfcollectdBinderService::new()?;
68 binder::add_service(
Chris Wailes8f571e12021-07-27 16:04:09 -070069 PROFCOLLECTD_SERVICE_NAME,
Andrew Walbran064c3652021-04-14 13:53:09 +000070 BnProfCollectd::new_binder(profcollect_binder_service, BinderFeatures::default())
71 .as_binder(),
Yi Konge3aab142021-03-02 13:58:25 +080072 )
73 .context("Failed to register service.")?;
74
75 if schedule_now {
Yabin Cuif158a752022-01-10 15:35:59 -080076 let cb = BnProviderStatusCallback::new_binder(
77 ProviderStatusCallback { service_start_time: Instant::now() },
78 BinderFeatures::default(),
79 );
80 get_profcollectd_service()?.registerProviderStatusCallback(&cb)?;
Yi Konge5576ae2020-08-05 02:00:05 +080081 }
Yi Konge3aab142021-03-02 13:58:25 +080082
83 binder::ProcessState::join_thread_pool();
84 Ok(())
Yi Konge5576ae2020-08-05 02:00:05 +080085}
86
Yi Kong74071ea2021-04-10 16:28:30 +080087fn get_profcollectd_service() -> Result<binder::Strong<dyn IProfCollectd::IProfCollectd>> {
Frederick Mayle6b7ad7e2024-05-08 13:43:26 -070088 binder::wait_for_interface(PROFCOLLECTD_SERVICE_NAME)
Yi Kong74071ea2021-04-10 16:28:30 +080089 .context("Failed to get profcollectd binder service, is profcollectd running?")
Yi Konge3aab142021-03-02 13:58:25 +080090}
91
Yi Konge5576ae2020-08-05 02:00:05 +080092/// Schedule periodic profile collection.
Yi Konge3aab142021-03-02 13:58:25 +080093pub fn schedule() -> Result<()> {
Yi Kong74071ea2021-04-10 16:28:30 +080094 get_profcollectd_service()?.schedule()?;
Yi Kongc6d5ff12021-03-10 02:20:45 +080095 Ok(())
Yi Konge5576ae2020-08-05 02:00:05 +080096}
97
98/// Terminate periodic profile collection.
Yi Konge3aab142021-03-02 13:58:25 +080099pub fn terminate() -> Result<()> {
Yi Kong74071ea2021-04-10 16:28:30 +0800100 get_profcollectd_service()?.terminate()?;
Yi Kongc6d5ff12021-03-10 02:20:45 +0800101 Ok(())
Yi Konge5576ae2020-08-05 02:00:05 +0800102}
103
104/// Immediately schedule a one-off trace.
Yi Kongc26c15b2024-07-06 17:20:44 +0900105pub fn trace_system(tag: &str) -> Result<()> {
106 get_profcollectd_service()?.trace_system(tag)?;
Yi Kongc6d5ff12021-03-10 02:20:45 +0800107 Ok(())
Yi Konge5576ae2020-08-05 02:00:05 +0800108}
109
Yi Konge3aab142021-03-02 13:58:25 +0800110/// Process traces.
111pub fn process() -> Result<()> {
Yi Konge7627422021-11-15 16:20:02 +0800112 get_profcollectd_service()?.process()?;
Yi Kongc6d5ff12021-03-10 02:20:45 +0800113 Ok(())
Yi Konge5576ae2020-08-05 02:00:05 +0800114}
115
Yi Konge3aab142021-03-02 13:58:25 +0800116/// Process traces and report profile.
Yi Kong037bde82021-03-23 14:25:38 +0800117pub fn report() -> Result<String> {
Yabin Cui1c3d80e2023-05-12 20:47:27 +0000118 Ok(get_profcollectd_service()?.report(report::NO_USAGE_SETTING)?)
Yi Kong4e25de72020-09-08 14:43:33 +0800119}
120
Yi Kong34ebf872021-11-29 19:57:55 +0800121/// Clear all local data.
122pub fn reset() -> Result<()> {
123 config::clear_data()?;
124 Ok(())
125}
126
Yi Konge3aab142021-03-02 13:58:25 +0800127/// Inits logging for Android
128pub fn init_logging() {
Jeff Vander Stoep743b98e2024-01-29 19:39:15 +0100129 let max_log_level =
130 if cfg!(feature = "test") { log::LevelFilter::Info } else { log::LevelFilter::Error };
Yi Konge3aab142021-03-02 13:58:25 +0800131 android_logger::init_once(
Yi Kongd1cca102022-02-23 21:26:09 +0800132 android_logger::Config::default()
133 .with_tag("profcollectd")
Jeff Vander Stoep743b98e2024-01-29 19:39:15 +0100134 .with_max_level(max_log_level)
135 .with_log_buffer(android_logger::LogId::System),
Yi Konge3aab142021-03-02 13:58:25 +0800136 );
Yi Konge5576ae2020-08-05 02:00:05 +0800137}