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

Commit 3efec4d2 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 11355999 from b2e2eefa to 24Q2-release

Change-Id: Ic1fbe7fedd6aa0a4823660c12e103aa12aecedf6
parents 5596e949 b2e2eefa
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -17,4 +17,4 @@

package android.view;

@JavaOnlyStableParcelable @NdkOnlyStableParcelable parcelable Surface cpp_header "gui/view/Surface.h" ndk_header "android/native_window_aidl.h";
@JavaOnlyStableParcelable @NdkOnlyStableParcelable @RustOnlyStableParcelable parcelable Surface cpp_header "gui/view/Surface.h" ndk_header "android/native_window_aidl.h" rust_type "nativewindow::Surface";
+23 −10
Original line number Diff line number Diff line
@@ -40,15 +40,12 @@ class BinderCallback : public LooperCallback {
public:
    static sp<BinderCallback> setupTo(const sp<Looper>& looper) {
        sp<BinderCallback> cb = sp<BinderCallback>::make();
        cb->mLooper = looper;

        int binder_fd = -1;
        IPCThreadState::self()->setupPolling(&binder_fd);
        LOG_ALWAYS_FATAL_IF(binder_fd < 0, "Failed to setupPolling: %d", binder_fd);
        IPCThreadState::self()->setupPolling(&cb->mBinderFd);
        LOG_ALWAYS_FATAL_IF(cb->mBinderFd < 0, "Failed to setupPolling: %d", cb->mBinderFd);

        int ret = looper->addFd(binder_fd,
                                Looper::POLL_CALLBACK,
                                Looper::EVENT_INPUT,
                                cb,
        int ret = looper->addFd(cb->mBinderFd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, cb,
                                nullptr /*data*/);
        LOG_ALWAYS_FATAL_IF(ret != 1, "Failed to add binder FD to Looper");

@@ -59,13 +56,26 @@ public:
        IPCThreadState::self()->handlePolledCommands();
        return 1;  // Continue receiving callbacks.
    }

    void repoll() {
        if (!mLooper->repoll(mBinderFd)) {
            ALOGE("Failed to repoll binder FD.");
        }
    }

private:
    sp<Looper> mLooper;
    int mBinderFd = -1;
};

// LooperCallback for IClientCallback
class ClientCallbackCallback : public LooperCallback {
public:
    static sp<ClientCallbackCallback> setupTo(const sp<Looper>& looper, const sp<ServiceManager>& manager) {
    static sp<ClientCallbackCallback> setupTo(const sp<Looper>& looper,
                                              const sp<ServiceManager>& manager,
                                              sp<BinderCallback> binderCallback) {
        sp<ClientCallbackCallback> cb = sp<ClientCallbackCallback>::make(manager);
        cb->mBinderCallback = binderCallback;

        int fdTimer = timerfd_create(CLOCK_MONOTONIC, 0 /*flags*/);
        LOG_ALWAYS_FATAL_IF(fdTimer < 0, "Failed to timerfd_create: fd: %d err: %d", fdTimer, errno);
@@ -102,12 +112,15 @@ public:
        }

        mManager->handleClientCallbacks();
        mBinderCallback->repoll(); // b/316829336

        return 1;  // Continue receiving callbacks.
    }
private:
    friend sp<ClientCallbackCallback>;
    ClientCallbackCallback(const sp<ServiceManager>& manager) : mManager(manager) {}
    sp<ServiceManager> mManager;
    sp<BinderCallback> mBinderCallback;
};

int main(int argc, char** argv) {
@@ -139,8 +152,8 @@ int main(int argc, char** argv) {

    sp<Looper> looper = Looper::prepare(false /*allowNonCallbacks*/);

    BinderCallback::setupTo(looper);
    ClientCallbackCallback::setupTo(looper, manager);
    sp<BinderCallback> binderCallback = BinderCallback::setupTo(looper);
    ClientCallbackCallback::setupTo(looper, manager, binderCallback);

#ifndef VENDORSERVICEMANAGER
    if (!SetProperty("servicemanager.ready", "true")) {
+7 −0
Original line number Diff line number Diff line
@@ -97,3 +97,10 @@ flag {
  description: "Change the acceleration curves for mouse pointer movements to match the touchpad ones"
  bug: "315313622"
}

flag {
  name: "rate_limit_user_activity_poke_in_dispatcher"
  namespace: "input"
  description: "Move user-activity poke rate-limiting from PowerManagerService to InputDispatcher."
  bug: "320499729"
}
+3 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

extern crate nativewindow_bindgen as ffi;

pub mod surface;

pub use ffi::{AHardwareBuffer_Format, AHardwareBuffer_UsageFlags};

use binder::{
@@ -210,7 +212,7 @@ impl Drop for HardwareBuffer {
}

impl Debug for HardwareBuffer {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        f.debug_struct("HardwareBuffer").field("id", &self.id()).finish()
    }
}
+140 −0
Original line number Diff line number Diff line
// Copyright (C) 2024 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.

//! Rust wrapper for `ANativeWindow` and related types.

use binder::{
    binder_impl::{BorrowedParcel, UnstructuredParcelable},
    impl_deserialize_for_unstructured_parcelable, impl_serialize_for_unstructured_parcelable,
    unstable_api::{status_result, AsNative},
    StatusCode,
};
use nativewindow_bindgen::{
    AHardwareBuffer_Format, ANativeWindow, ANativeWindow_acquire, ANativeWindow_getFormat,
    ANativeWindow_getHeight, ANativeWindow_getWidth, ANativeWindow_readFromParcel,
    ANativeWindow_release, ANativeWindow_writeToParcel,
};
use std::error::Error;
use std::fmt::{self, Debug, Display, Formatter};
use std::ptr::{null_mut, NonNull};

/// Wrapper around an opaque C `ANativeWindow`.
#[derive(PartialEq, Eq)]
pub struct Surface(NonNull<ANativeWindow>);

impl Surface {
    /// Returns the current width in pixels of the window surface.
    pub fn width(&self) -> Result<u32, ErrorCode> {
        // SAFETY: The ANativeWindow pointer we pass is guaranteed to be non-null and valid because
        // it must have been allocated by `ANativeWindow_allocate` or `ANativeWindow_readFromParcel`
        // and we have not yet released it.
        let width = unsafe { ANativeWindow_getWidth(self.0.as_ptr()) };
        width.try_into().map_err(|_| ErrorCode(width))
    }

    /// Returns the current height in pixels of the window surface.
    pub fn height(&self) -> Result<u32, ErrorCode> {
        // SAFETY: The ANativeWindow pointer we pass is guaranteed to be non-null and valid because
        // it must have been allocated by `ANativeWindow_allocate` or `ANativeWindow_readFromParcel`
        // and we have not yet released it.
        let height = unsafe { ANativeWindow_getHeight(self.0.as_ptr()) };
        height.try_into().map_err(|_| ErrorCode(height))
    }

    /// Returns the current pixel format of the window surface.
    pub fn format(&self) -> Result<AHardwareBuffer_Format::Type, ErrorCode> {
        // SAFETY: The ANativeWindow pointer we pass is guaranteed to be non-null and valid because
        // it must have been allocated by `ANativeWindow_allocate` or `ANativeWindow_readFromParcel`
        // and we have not yet released it.
        let format = unsafe { ANativeWindow_getFormat(self.0.as_ptr()) };
        format.try_into().map_err(|_| ErrorCode(format))
    }
}

impl Drop for Surface {
    fn drop(&mut self) {
        // SAFETY: The ANativeWindow pointer we pass is guaranteed to be non-null and valid because
        // it must have been allocated by `ANativeWindow_allocate` or `ANativeWindow_readFromParcel`
        // and we have not yet released it.
        unsafe { ANativeWindow_release(self.0.as_ptr()) }
    }
}

impl Debug for Surface {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        f.debug_struct("Surface")
            .field("width", &self.width())
            .field("height", &self.height())
            .field("format", &self.format())
            .finish()
    }
}

impl Clone for Surface {
    fn clone(&self) -> Self {
        // SAFETY: The ANativeWindow pointer we pass is guaranteed to be non-null and valid because
        // it must have been allocated by `ANativeWindow_allocate` or `ANativeWindow_readFromParcel`
        // and we have not yet released it.
        unsafe { ANativeWindow_acquire(self.0.as_ptr()) };
        Self(self.0)
    }
}

impl UnstructuredParcelable for Surface {
    fn write_to_parcel(&self, parcel: &mut BorrowedParcel) -> Result<(), StatusCode> {
        let status =
        // SAFETY: The ANativeWindow pointer we pass is guaranteed to be non-null and valid because
        // it must have been allocated by `ANativeWindow_allocate` or `ANativeWindow_readFromParcel`
        // and we have not yet released it.
        unsafe { ANativeWindow_writeToParcel(self.0.as_ptr(), parcel.as_native_mut()) };
        status_result(status)
    }

    fn from_parcel(parcel: &BorrowedParcel) -> Result<Self, StatusCode> {
        let mut buffer = null_mut();

        let status =
        // SAFETY: Both pointers must be valid because they are obtained from references.
        // `ANativeWindow_readFromParcel` doesn't store them or do anything else special
        // with them. If it returns success then it will have allocated a new
        // `ANativeWindow` and incremented the reference count, so we can use it until we
        // release it.
            unsafe { ANativeWindow_readFromParcel(parcel.as_native(), &mut buffer) };

        status_result(status)?;

        Ok(Self(
            NonNull::new(buffer)
                .expect("ANativeWindow_readFromParcel returned success but didn't allocate buffer"),
        ))
    }
}

impl_deserialize_for_unstructured_parcelable!(Surface);
impl_serialize_for_unstructured_parcelable!(Surface);

// SAFETY: The underlying *ANativeWindow can be moved between threads.
unsafe impl Send for Surface {}

/// An error code returned by methods on [`Surface`].
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct ErrorCode(i32);

impl Error for ErrorCode {}

impl Display for ErrorCode {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "Error {}", self.0)
    }
}
Loading