summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--profcollectd/binder/com/android/server/profcollect/IProfCollectd.aidl1
-rw-r--r--profcollectd/libprofcollectd/config.rs3
-rw-r--r--profcollectd/libprofcollectd/report.rs18
-rw-r--r--profcollectd/libprofcollectd/service.rs37
4 files changed, 45 insertions, 14 deletions
diff --git a/profcollectd/binder/com/android/server/profcollect/IProfCollectd.aidl b/profcollectd/binder/com/android/server/profcollect/IProfCollectd.aidl
index 9d4985b4..58503abc 100644
--- a/profcollectd/binder/com/android/server/profcollect/IProfCollectd.aidl
+++ b/profcollectd/binder/com/android/server/profcollect/IProfCollectd.aidl
@@ -23,6 +23,7 @@ interface IProfCollectd {
void trace_once(@utf8InCpp String tag);
void process(boolean blocking);
@utf8InCpp String report();
+ void copy_report_to_bb(int bb_profile_id, @utf8InCpp String report);
void delete_report(@utf8InCpp String report);
@utf8InCpp String get_supported_provider();
}
diff --git a/profcollectd/libprofcollectd/config.rs b/profcollectd/libprofcollectd/config.rs
index c0f91d53..112f9efc 100644
--- a/profcollectd/libprofcollectd/config.rs
+++ b/profcollectd/libprofcollectd/config.rs
@@ -33,6 +33,9 @@ lazy_static! {
pub static ref TRACE_OUTPUT_DIR: &'static Path = Path::new("/data/misc/profcollectd/trace/");
pub static ref PROFILE_OUTPUT_DIR: &'static Path = Path::new("/data/misc/profcollectd/output/");
pub static ref REPORT_OUTPUT_DIR: &'static Path = Path::new("/data/misc/profcollectd/report/");
+ pub static ref BETTERBUG_CACHE_DIR_PREFIX: &'static Path = Path::new("/data/user/");
+ pub static ref BETTERBUG_CACHE_DIR_SUFFIX: &'static Path =
+ Path::new("com.google.android.apps.internal.betterbug/cache/");
pub static ref OLD_REPORT_OUTPUT_FILE: &'static Path =
Path::new("/data/misc/profcollectd/report.zip");
pub static ref CONFIG_FILE: &'static Path =
diff --git a/profcollectd/libprofcollectd/report.rs b/profcollectd/libprofcollectd/report.rs
index 218ec875..2c524729 100644
--- a/profcollectd/libprofcollectd/report.rs
+++ b/profcollectd/libprofcollectd/report.rs
@@ -19,8 +19,9 @@
use anyhow::{anyhow, Result};
use lazy_static::lazy_static;
use macaddr::MacAddr6;
-use std::fs::{read_dir, remove_file, File};
+use std::fs::{self, File};
use std::io::{Read, Write};
+use std::os::unix::fs::OpenOptionsExt;
use std::path::{Path, PathBuf};
use std::time::SystemTime;
use uuid::v1::{Context, Timestamp};
@@ -36,19 +37,20 @@ lazy_static! {
pub fn pack_report(profile: &Path, report: &Path, config: &Config) -> Result<String> {
let mut report = PathBuf::from(report);
- report.push(get_report_filename(&config.node_id)?);
+ let report_filename = get_report_filename(&config.node_id)?;
+ report.push(&report_filename);
report.set_extension("zip");
- let report_path =
- report.to_str().ok_or_else(|| anyhow!("Malformed report path: {}", report.display()))?;
// Remove the current report file if exists.
- remove_file(&report).ok();
+ fs::remove_file(&report).ok();
- let report = File::create(&report)?;
+ // Set report file ACL bits to 644, so that this can be shared to uploaders.
+ // Who has permission to actually read the file is protected by SELinux policy.
+ let report = fs::OpenOptions::new().create_new(true).write(true).mode(0o644).open(&report)?;
let options = FileOptions::default();
let mut zip = ZipWriter::new(report);
- read_dir(profile)?
+ fs::read_dir(profile)?
.filter_map(|e| e.ok())
.map(|e| e.path())
.filter(|e| e.is_file())
@@ -66,7 +68,7 @@ pub fn pack_report(profile: &Path, report: &Path, config: &Config) -> Result<Str
})?;
zip.finish()?;
- Ok(report_path.to_string())
+ Ok(report_filename)
}
fn get_report_filename(node_id: &MacAddr6) -> Result<String> {
diff --git a/profcollectd/libprofcollectd/service.rs b/profcollectd/libprofcollectd/service.rs
index 4bc08970..dc622ff3 100644
--- a/profcollectd/libprofcollectd/service.rs
+++ b/profcollectd/libprofcollectd/service.rs
@@ -16,25 +16,26 @@
//! ProfCollect Binder service implementation.
-use anyhow::{bail, Context, Error, Result};
+use anyhow::{anyhow, bail, Context, Error, Result};
use binder::public_api::Result as BinderResult;
use binder::Status;
use profcollectd_aidl_interface::aidl::com::android::server::profcollect::IProfCollectd::IProfCollectd;
use std::ffi::CString;
-use std::fs::{create_dir, read_to_string, remove_dir_all, remove_file, write};
+use std::fs::{copy, create_dir, read_to_string, remove_dir_all, remove_file, write};
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::{Mutex, MutexGuard};
use crate::config::{
- Config, CONFIG_FILE, OLD_REPORT_OUTPUT_FILE, PROFILE_OUTPUT_DIR, REPORT_OUTPUT_DIR,
- TRACE_OUTPUT_DIR,
+ Config, BETTERBUG_CACHE_DIR_PREFIX, BETTERBUG_CACHE_DIR_SUFFIX, CONFIG_FILE,
+ OLD_REPORT_OUTPUT_FILE, PROFILE_OUTPUT_DIR, REPORT_OUTPUT_DIR, TRACE_OUTPUT_DIR,
};
use crate::report::pack_report;
use crate::scheduler::Scheduler;
fn err_to_binder_status(msg: Error) -> Status {
- let msg = CString::new(msg.to_string()).expect("Failed to convert to CString");
+ let msg = format!("{:#?}", msg);
+ let msg = CString::new(msg).expect("Failed to convert to CString");
Status::new_service_specific_error(1, Some(&msg))
}
@@ -95,6 +96,30 @@ impl IProfCollectd for ProfcollectdBinderService {
remove_file(&report).ok();
Ok(())
}
+ fn copy_report_to_bb(&self, bb_profile_id: i32, report_name: &str) -> BinderResult<()> {
+ if bb_profile_id < 0 {
+ return Err(err_to_binder_status(anyhow!("Invalid profile ID")));
+ }
+ verify_report_name(&report_name).map_err(err_to_binder_status)?;
+
+ let mut report = PathBuf::from(&*REPORT_OUTPUT_DIR);
+ report.push(report_name);
+ report.set_extension("zip");
+
+ let mut dest = PathBuf::from(&*BETTERBUG_CACHE_DIR_PREFIX);
+ dest.push(bb_profile_id.to_string());
+ dest.push(&*BETTERBUG_CACHE_DIR_SUFFIX);
+ if !dest.is_dir() {
+ return Err(err_to_binder_status(anyhow!("Cannot open BetterBug cache dir")));
+ }
+ dest.push(report_name);
+ dest.set_extension("zip");
+
+ copy(report, dest)
+ .map(|_| ())
+ .context("Failed to copy report to bb storage.")
+ .map_err(err_to_binder_status)
+ }
fn get_supported_provider(&self) -> BinderResult<String> {
Ok(self.lock().scheduler.get_trace_provider_name().to_string())
}
@@ -105,7 +130,7 @@ impl IProfCollectd for ProfcollectdBinderService {
fn verify_report_name(report_name: &str) -> Result<()> {
match report_name.chars().all(|c| c.is_ascii_hexdigit() || c == '-') {
true => Ok(()),
- false => bail!("Not a report name: {}", report_name),
+ false => bail!("Invalid report name: {}", report_name),
}
}