Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 804fe8db authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 13412669 from 218da5d7 to 25Q4-release

Change-Id: I9788c37de9634472364261eab1d964119cbd7df4
parents 60c5282e 218da5d7
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -1752,6 +1752,7 @@ Dumpstate::RunStatus Dumpstate::dumpstate() {
    DumpFile("ZONEINFO", "/proc/zoneinfo");
    DumpFile("PAGETYPEINFO", "/proc/pagetypeinfo");
    DumpFile("BUDDYINFO", "/proc/buddyinfo");
    DumpFile("MGLRU", "/sys/kernel/mm/lru_gen/enabled");
    DumpExternalFragmentationInfo();

    DumpFile("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
@@ -3459,6 +3460,7 @@ Dumpstate::RunStatus Dumpstate::RunInternal(int32_t calling_uid,
    }

    MaybeTakeEarlyScreenshot();
    MaybeSavePlaceholderScreenshot();
    MaybeWaitForSnapshotSystemTrace(std::move(snapshot_system_trace));
    onUiIntensiveBugreportDumpsFinished(calling_uid);
    MaybeCheckUserConsent(calling_uid, calling_package);
@@ -3558,6 +3560,26 @@ void Dumpstate::MaybeTakeEarlyScreenshot() {
    TakeScreenshot();
}

void Dumpstate::MaybeSavePlaceholderScreenshot() {
    if (options_->do_screenshot) {
        // No need to save a placeholder screenshot if a real one will be taken.
        return;
    }
    if (!options_->is_consent_deferred) {
        return;
    }

    // When consent is deferred, a screenshot used to be taken even when one
    // was not requested. The screenshot is not taken any more but a placeholder
    // is saved for backwards compatibility.
    std::string path = ds.GetPath(ds.CalledByApi() ? "-png.tmp" : ".png");
    if (android::os::CopyFileToFile(DEFAULT_SCREENSHOT_PATH, path)) {
        MYLOGD("Saved fallback screenshot on %s\n", path.c_str());
    } else {
        MYLOGE("Failed to save fallback screenshot on %s\n", path.c_str());
    };
}

std::future<std::string> Dumpstate::MaybeSnapshotSystemTraceAsync() {
    // When capturing traces via bugreport handler (BH), this function will be invoked twice:
    // 1) When BH invokes IDumpstate::PreDumpUiData()
+1 −0
Original line number Diff line number Diff line
@@ -573,6 +573,7 @@ class Dumpstate {
    RunStatus dumpstate();

    void MaybeTakeEarlyScreenshot();
    void MaybeSavePlaceholderScreenshot();
    std::future<std::string> MaybeSnapshotSystemTraceAsync();
    void MaybeWaitForSnapshotSystemTrace(std::future<std::string> task);
    void MaybeSnapshotUiTraces();
+32 −0
Original line number Diff line number Diff line
@@ -1082,6 +1082,38 @@ TEST_F(ZippedBugReportStreamTest, DISABLED_StreamLimitedOnlyReport) {
    VerifyEntry(handle_, bugreport_txt_name, &entry);
}

TEST_F(ZippedBugReportStreamTest, ScreenShotFileCreated) {
    std::string out_path = kTestDataPath + "ScreenShotCapturedOut.zip";
    android::base::unique_fd out_fd;
    CreateFd(out_path, &out_fd);
    ds_.options_->limited_only = true;
    ds_.options_->stream_to_socket = true;
    ds_.options_->do_screenshot = false;
    ds_.options_->is_consent_deferred = true;
    RedirectOutputToFd(out_fd);

    GenerateBugreport();

    std::string screenshot = ds_.GetPath(ds_.CalledByApi() ? "-png.tmp" : ".png");
    EXPECT_TRUE(std::filesystem::exists(screenshot)) << screenshot << " was not created.";
}

TEST_F(ZippedBugReportStreamTest, ScreenShotFileIsNotCreated) {
    std::string out_path = kTestDataPath + "ScreenShotCapturedOut.zip";
    android::base::unique_fd out_fd;
    CreateFd(out_path, &out_fd);
    ds_.options_->limited_only = true;
    ds_.options_->stream_to_socket = true;
    ds_.options_->do_screenshot = false;
    ds_.options_->is_consent_deferred = false;
    RedirectOutputToFd(out_fd);

    GenerateBugreport();

    std::string screenshot = ds_.GetPath(ds_.CalledByApi() ? "-png.tmp" : ".png");
    EXPECT_FALSE(std::filesystem::exists(screenshot)) << screenshot << " was created.";
}

class ProgressTest : public DumpstateBaseTest {
  public:
    Progress GetInstance(int32_t max, double growth_factor, const std::string& path = "") {
+26 −0
Original line number Diff line number Diff line
package {
    // See: http://go/android-license-faq
    // A large-scale-change added 'default_applicable_licenses' to import
    // all of the 'license_kinds' from "frameworks_native_license"
    // to get the below license kinds:
    //   SPDX-license-identifier-Apache-2.0
    default_applicable_licenses: ["frameworks_native_license"],
}

rust_library {
    name: "librpc_servicemanager",
    crate_name: "rpc_servicemanager",
    srcs: ["rpc_servicemanager.rs"],
    rustlibs: [
        "android.system.virtualmachineservice-rust",
        "libanyhow",
        "libbinder_rs",
        "liblibc",
        "liblog_rust",
        "librpcbinder_rs",
        "librustutils",
        "libvsock",
        "rpc_servicemanager_aidl-rust",
        "servicemanager_aidl-rust",
    ],
}
+195 −0
Original line number Diff line number Diff line
// Copyright 2025, 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.

//! Implementation of the AIDL interface `IServiceManager`.

use anyhow::Result;
use binder::{Accessor, BinderFeatures, Interface, Strong};
use libc::{sa_family_t, sockaddr_vm, AF_VSOCK};
use log::{error, info};
use rpc_servicemanager_aidl::aidl::android::os::IRpcProvider::{
    IRpcProvider, ServiceConnectionInfo::ServiceConnectionInfo,
};
use rpcbinder::{FileDescriptorTransportMode, RpcServer};
use rustutils::sockets::{android_get_control_socket, SocketError};
use servicemanager_aidl::aidl::android::os::IServiceManager::{
    BnServiceManager, CallerContext::CallerContext, IServiceManager,
};
use servicemanager_aidl::aidl::android::os::{
    ConnectionInfo::ConnectionInfo, IClientCallback::IClientCallback,
    IServiceCallback::IServiceCallback, Service::Service, ServiceDebugInfo::ServiceDebugInfo,
};
use std::os::unix::io::OwnedFd;
use vsock::VMADDR_CID_HOST;

// Name of the socket that libbinder is expecting IServiceManager to be served from
const RPC_SERVICEMANAGER_UDS_NAME: &str = "rpc_servicemanager";

/// Implementation of `IServiceManager`.
pub struct RpcServiceManager {
    provider_service: Strong<dyn IRpcProvider>,
}

impl IServiceManager for RpcServiceManager {
    fn getService(&self, _name: &str) -> binder::Result<Option<binder::SpIBinder>> {
        Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into())
    }
    fn getService2(&self, name: &str) -> binder::Result<Service> {
        let provider_service = self.provider_service.clone();

        let get_connection_info = move |inst: &str| {
            let connection_info = provider_service.getServiceConnectionInfo(inst).unwrap();
            match connection_info {
                ServiceConnectionInfo::Vsock(info) => {
                    let addr = sockaddr_vm {
                        svm_family: AF_VSOCK as sa_family_t,
                        svm_reserved1: 0,
                        svm_port: info.port as u32,
                        svm_cid: VMADDR_CID_HOST,
                        svm_zero: [0u8; 4],
                    };
                    Some(binder::ConnectionInfo::Vsock(addr))
                }
                #[allow(unreachable_patterns)]
                _ => {
                    error!("Unexpected ServiceConnectionInfo type!");
                    None
                }
            }
        };

        let accessor = Accessor::new(name, get_connection_info);

        Ok(Service::Accessor(accessor.as_binder()))
    }
    fn checkService(&self, _name: &str) -> binder::Result<Option<binder::SpIBinder>> {
        Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into())
    }
    fn checkService2(&self, _name: &str) -> binder::Result<Service> {
        Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into())
    }
    fn addService(
        &self,
        _name: &str,
        _service: &binder::SpIBinder,
        _allow_isolated: bool,
        _dump_priority: i32,
    ) -> binder::Result<()> {
        Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into())
    }
    fn listServices(&self, _dump_priority: i32) -> binder::Result<Vec<String>> {
        Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into())
    }
    fn registerForNotifications(
        &self,
        _name: &str,
        _callback: &binder::Strong<dyn IServiceCallback>,
    ) -> binder::Result<()> {
        Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into())
    }
    fn unregisterForNotifications(
        &self,
        _name: &str,
        _callback: &binder::Strong<dyn IServiceCallback>,
    ) -> binder::Result<()> {
        Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into())
    }
    fn isDeclared(&self, _name: &str) -> binder::Result<bool> {
        Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into())
    }
    fn getDeclaredInstances(&self, _iface: &str) -> binder::Result<Vec<String>> {
        Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into())
    }
    fn updatableViaApex(&self, _name: &str) -> binder::Result<Option<String>> {
        Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into())
    }
    fn getUpdatableNames(&self, _apex_name: &str) -> binder::Result<Vec<String>> {
        Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into())
    }
    fn getConnectionInfo(&self, _name: &str) -> binder::Result<Option<ConnectionInfo>> {
        Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into())
    }
    fn registerClientCallback(
        &self,
        _name: &str,
        _service: &binder::SpIBinder,
        _callback: &binder::Strong<dyn IClientCallback>,
    ) -> binder::Result<()> {
        Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into())
    }
    fn tryUnregisterService(
        &self,
        _name: &str,
        _service: &binder::SpIBinder,
    ) -> binder::Result<()> {
        Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into())
    }
    fn getServiceDebugInfo(&self) -> binder::Result<Vec<ServiceDebugInfo>> {
        Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into())
    }
    fn checkServiceAccess(&self, _: &CallerContext, _: &str, _: &str) -> binder::Result<bool> {
        Err(binder::ExceptionCode::UNSUPPORTED_OPERATION.into())
    }
}

impl Interface for RpcServiceManager {}

impl RpcServiceManager {
    /// Creates a new `RpcServiceManager` instance from the `IServiceManager` reference.
    fn new(provider_service: Strong<dyn IRpcProvider>) -> RpcServiceManager {
        Self { provider_service }
    }
}

/// Get the Unix Domain Socket file descriptor for RPC_SERVICEMANAGER_UDS_NAME
///
/// A client might need to do this in order to get an FD with the FD_CLOEXEC flag set before
/// it forks any other processes.
pub fn get_default_rpc_servicemanager_uds_fd() -> Result<OwnedFd, SocketError> {
    android_get_control_socket(RPC_SERVICEMANAGER_UDS_NAME)
}

/// Registers the `IServiceManager` service.
///
/// servicemanager_fd is an optional argument to provide the Unix Domain Socked file
/// descriptor to use for the server. If None is provided, then it will use the default
/// of RPC_SERVICEMANAGER_UDS_NAME to get the FD.
pub fn register_rpc_servicemanager(
    provider_service: Strong<dyn IRpcProvider>,
    servicemanager_fd: Option<OwnedFd>,
) -> Result<()> {
    let rpc_servicemanager_binder = BnServiceManager::new_binder(
        RpcServiceManager::new(provider_service),
        BinderFeatures::default(),
    );
    let servicemanager_fd = match servicemanager_fd {
        Some(fd) => fd,
        None => android_get_control_socket(RPC_SERVICEMANAGER_UDS_NAME)?,
    };
    let server =
        RpcServer::new_bound_socket(rpc_servicemanager_binder.as_binder(), servicemanager_fd)?;
    // Required for the FD being passed through libbinder's accessor binder
    server.set_supported_file_descriptor_transport_modes(&[FileDescriptorTransportMode::Unix]);

    info!("The RPC server '{}' is running.", RPC_SERVICEMANAGER_UDS_NAME);
    if let Err(e) = rustutils::system_properties::write("servicemanager.ready", "true") {
        error!("failed to set ro.servicemanager.ready {:?}", e);
    }

    // Move server reference into a background thread and run it forever.
    std::thread::spawn(move || {
        server.join();
    });
    Ok(())
}
Loading