Loading include/android/imagedecoder.h +17 −9 Original line number Diff line number Diff line Loading @@ -837,9 +837,11 @@ void AImageDecoderFrameInfo_delete( * is the current frame. * * If the image only has one frame, this will fill the {@link * AImageDecoderFrameInfo} with the encoded info, if any, or reasonable * AImageDecoderFrameInfo} with the encoded info and reasonable * defaults. * * If {@link AImageDecoder_advanceFrame} succeeded, this will succeed as well. * * @param decoder Opaque object representing the decoder. * @param info Opaque object to hold frame information. On success, will be * filled with information regarding the current frame. Loading @@ -861,7 +863,7 @@ int AImageDecoder_getFrameInfo(AImageDecoder* _Nonnull decoder, * Introduced in API 31. * * Errors: * - returns 0 if |info| is null. * - returns {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER} if |info| is null. */ int64_t AImageDecoderFrameInfo_getDuration( const AImageDecoderFrameInfo* _Nonnull info) __INTRODUCED_IN(31); Loading Loading @@ -896,19 +898,25 @@ ARect AImageDecoderFrameInfo_getFrameRect( * * Introduced in API 31. * * Note that this may differ from whether the composed frame has * alpha. If this frame does not fill the entire image dimensions * (see {@link AImageDecoderFrameInfo_getFrameRect}) or it blends * with an opaque frame, for example, the composed frame’s alpha * may not match. It is also conservative; for example, if a color * index-based frame has a color with alpha but does not use it, * this will still return true. * Unless this frame is independent (see {@link AImageDecoder_decodeImage}), * a single call to {@link AImageDecoder_decodeImage} will decode an updated * rectangle of pixels and then blend it with the existing pixels in the * |pixels| buffer according to {@link AImageDecoderFrameInfo_getBlendOp}. This * method returns whether the updated rectangle has alpha, prior to blending. * The return value is conservative; for example, if a color-index-based frame * has a color with alpha but does not use it, this will still return true. * * This, along with other information in AImageDecoderFrameInfo, * can be useful for determining whether a frame is independent, but * the decoder handles blending frames, so a simple * sequential client does not need this. * * Note that this may differ from whether the composed frame (that is, the * resulting image after blending) has alpha. If this frame does not fill the * entire image dimensions (see {@link AImageDecoderFrameInfo_getFrameRect}) * or it blends with an opaque frame, for example, the composed frame’s alpha * may not match. * * Errors: * - returns false if |info| is null. */ Loading libs/binder/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -112,7 +112,7 @@ cc_library { "PersistableBundle.cpp", "ProcessState.cpp", "RpcAddress.cpp", "RpcConnection.cpp", "RpcSession.cpp", "RpcServer.cpp", "RpcState.cpp", "Static.cpp", Loading libs/binder/BpBinder.cpp +14 −14 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ #include <binder/IPCThreadState.h> #include <binder/IResultReceiver.h> #include <binder/RpcConnection.h> #include <binder/RpcSession.h> #include <binder/Stability.h> #include <cutils/compiler.h> #include <utils/Log.h> Loading Loading @@ -136,15 +136,15 @@ sp<BpBinder> BpBinder::create(int32_t handle) { return sp<BpBinder>::make(BinderHandle{handle}, trackedUid); } sp<BpBinder> BpBinder::create(const sp<RpcConnection>& connection, const RpcAddress& address) { LOG_ALWAYS_FATAL_IF(connection == nullptr, "BpBinder::create null connection"); sp<BpBinder> BpBinder::create(const sp<RpcSession>& session, const RpcAddress& address) { LOG_ALWAYS_FATAL_IF(session == nullptr, "BpBinder::create null session"); // These are not currently tracked, since there is no UID or other // identifier to track them with. However, if similar functionality is // needed, connection objects keep track of all BpBinder objects on a // per-connection basis. // needed, session objects keep track of all BpBinder objects on a // per-session basis. return sp<BpBinder>::make(SocketHandle{connection, address}); return sp<BpBinder>::make(RpcHandle{session, address}); } BpBinder::BpBinder(Handle&& handle) Loading @@ -165,20 +165,20 @@ BpBinder::BpBinder(BinderHandle&& handle, int32_t trackedUid) : BpBinder(Handle( IPCThreadState::self()->incWeakHandle(this->binderHandle(), this); } BpBinder::BpBinder(SocketHandle&& handle) : BpBinder(Handle(handle)) { LOG_ALWAYS_FATAL_IF(rpcConnection() == nullptr, "BpBinder created w/o connection object"); BpBinder::BpBinder(RpcHandle&& handle) : BpBinder(Handle(handle)) { LOG_ALWAYS_FATAL_IF(rpcSession() == nullptr, "BpBinder created w/o session object"); } bool BpBinder::isRpcBinder() const { return std::holds_alternative<SocketHandle>(mHandle); return std::holds_alternative<RpcHandle>(mHandle); } const RpcAddress& BpBinder::rpcAddress() const { return std::get<SocketHandle>(mHandle).address; return std::get<RpcHandle>(mHandle).address; } const sp<RpcConnection>& BpBinder::rpcConnection() const { return std::get<SocketHandle>(mHandle).connection; const sp<RpcSession>& BpBinder::rpcSession() const { return std::get<RpcHandle>(mHandle).session; } int32_t BpBinder::binderHandle() const { Loading Loading @@ -273,7 +273,7 @@ status_t BpBinder::transact( status_t status; if (CC_UNLIKELY(isRpcBinder())) { status = rpcConnection()->transact(rpcAddress(), code, data, reply, flags); status = rpcSession()->transact(rpcAddress(), code, data, reply, flags); } else { status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags); } Loading Loading @@ -479,7 +479,7 @@ void BpBinder::onLastStrongRef(const void* /*id*/) { ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, binderHandle()); if (CC_UNLIKELY(isRpcBinder())) { (void)rpcConnection()->sendDecStrong(rpcAddress()); (void)rpcSession()->sendDecStrong(rpcAddress()); return; } IF_ALOGV() { Loading libs/binder/Parcel.cpp +9 −10 Original line number Diff line number Diff line Loading @@ -202,7 +202,7 @@ status_t Parcel::flattenBinder(const sp<IBinder>& binder) status_t status = writeInt32(1); // non-null if (status != OK) return status; RpcAddress address = RpcAddress::zero(); status = mConnection->state()->onBinderLeaving(mConnection, binder, &address); status = mSession->state()->onBinderLeaving(mSession, binder, &address); if (status != OK) return status; status = address.writeToParcel(this); if (status != OK) return status; Loading Loading @@ -273,8 +273,7 @@ status_t Parcel::flattenBinder(const sp<IBinder>& binder) status_t Parcel::unflattenBinder(sp<IBinder>* out) const { if (isForRpc()) { LOG_ALWAYS_FATAL_IF(mConnection == nullptr, "RpcConnection required to read from remote parcel"); LOG_ALWAYS_FATAL_IF(mSession == nullptr, "RpcSession required to read from remote parcel"); int32_t isNull; status_t status = readInt32(&isNull); Loading @@ -286,7 +285,7 @@ status_t Parcel::unflattenBinder(sp<IBinder>* out) const auto addr = RpcAddress::zero(); status_t status = addr.readFromParcel(*this); if (status != OK) return status; binder = mConnection->state()->onBinderEntering(mConnection, addr); binder = mSession->state()->onBinderEntering(mSession, addr); } return finishUnflattenBinder(binder, out); Loading Loading @@ -568,20 +567,20 @@ void Parcel::markForBinder(const sp<IBinder>& binder) { LOG_ALWAYS_FATAL_IF(mData != nullptr, "format must be set before data is written"); if (binder && binder->remoteBinder() && binder->remoteBinder()->isRpcBinder()) { markForRpc(binder->remoteBinder()->getPrivateAccessorForId().rpcConnection()); markForRpc(binder->remoteBinder()->getPrivateAccessorForId().rpcSession()); } } void Parcel::markForRpc(const sp<RpcConnection>& connection) { void Parcel::markForRpc(const sp<RpcSession>& session) { LOG_ALWAYS_FATAL_IF(mData != nullptr && mOwner == nullptr, "format must be set before data is written OR on IPC data"); LOG_ALWAYS_FATAL_IF(connection == nullptr, "markForRpc requires connection"); mConnection = connection; LOG_ALWAYS_FATAL_IF(session == nullptr, "markForRpc requires session"); mSession = session; } bool Parcel::isForRpc() const { return mConnection != nullptr; return mSession != nullptr; } void Parcel::updateWorkSourceRequestHeaderPosition() const { Loading Loading @@ -2499,7 +2498,7 @@ void Parcel::initState() mDataPos = 0; ALOGV("initState Setting data size of %p to %zu", this, mDataSize); ALOGV("initState Setting data pos of %p to %zu", this, mDataPos); mConnection = nullptr; mSession = nullptr; mObjects = nullptr; mObjectsSize = 0; mObjectsCapacity = 0; Loading libs/binder/RpcServer.cpp +17 −17 Original line number Diff line number Diff line Loading @@ -149,38 +149,38 @@ void RpcServer::join() { { std::lock_guard<std::mutex> _l(mLock); sp<RpcConnection> connection; if (id == RPC_CONNECTION_ID_NEW) { sp<RpcSession> session; if (id == RPC_SESSION_ID_NEW) { // new client! LOG_ALWAYS_FATAL_IF(mConnectionIdCounter >= INT32_MAX, "Out of connection IDs"); mConnectionIdCounter++; LOG_ALWAYS_FATAL_IF(mSessionIdCounter >= INT32_MAX, "Out of session IDs"); mSessionIdCounter++; connection = RpcConnection::make(); connection->setForServer(wp<RpcServer>::fromExisting(this), mConnectionIdCounter); session = RpcSession::make(); session->setForServer(wp<RpcServer>::fromExisting(this), mSessionIdCounter); mConnections[mConnectionIdCounter] = connection; mSessions[mSessionIdCounter] = session; } else { auto it = mConnections.find(id); if (it == mConnections.end()) { ALOGE("Cannot add thread, no record of connection with ID %d", id); auto it = mSessions.find(id); if (it == mSessions.end()) { ALOGE("Cannot add thread, no record of session with ID %d", id); continue; } connection = it->second; session = it->second; } connection->startThread(std::move(clientFd)); session->startThread(std::move(clientFd)); } } } std::vector<sp<RpcConnection>> RpcServer::listConnections() { std::vector<sp<RpcSession>> RpcServer::listSessions() { std::lock_guard<std::mutex> _l(mLock); std::vector<sp<RpcConnection>> connections; for (auto& [id, connection] : mConnections) { std::vector<sp<RpcSession>> sessions; for (auto& [id, session] : mSessions) { (void)id; connections.push_back(connection); sessions.push_back(session); } return connections; return sessions; } bool RpcServer::setupSocketServer(const RpcSocketAddress& addr) { Loading Loading
include/android/imagedecoder.h +17 −9 Original line number Diff line number Diff line Loading @@ -837,9 +837,11 @@ void AImageDecoderFrameInfo_delete( * is the current frame. * * If the image only has one frame, this will fill the {@link * AImageDecoderFrameInfo} with the encoded info, if any, or reasonable * AImageDecoderFrameInfo} with the encoded info and reasonable * defaults. * * If {@link AImageDecoder_advanceFrame} succeeded, this will succeed as well. * * @param decoder Opaque object representing the decoder. * @param info Opaque object to hold frame information. On success, will be * filled with information regarding the current frame. Loading @@ -861,7 +863,7 @@ int AImageDecoder_getFrameInfo(AImageDecoder* _Nonnull decoder, * Introduced in API 31. * * Errors: * - returns 0 if |info| is null. * - returns {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER} if |info| is null. */ int64_t AImageDecoderFrameInfo_getDuration( const AImageDecoderFrameInfo* _Nonnull info) __INTRODUCED_IN(31); Loading Loading @@ -896,19 +898,25 @@ ARect AImageDecoderFrameInfo_getFrameRect( * * Introduced in API 31. * * Note that this may differ from whether the composed frame has * alpha. If this frame does not fill the entire image dimensions * (see {@link AImageDecoderFrameInfo_getFrameRect}) or it blends * with an opaque frame, for example, the composed frame’s alpha * may not match. It is also conservative; for example, if a color * index-based frame has a color with alpha but does not use it, * this will still return true. * Unless this frame is independent (see {@link AImageDecoder_decodeImage}), * a single call to {@link AImageDecoder_decodeImage} will decode an updated * rectangle of pixels and then blend it with the existing pixels in the * |pixels| buffer according to {@link AImageDecoderFrameInfo_getBlendOp}. This * method returns whether the updated rectangle has alpha, prior to blending. * The return value is conservative; for example, if a color-index-based frame * has a color with alpha but does not use it, this will still return true. * * This, along with other information in AImageDecoderFrameInfo, * can be useful for determining whether a frame is independent, but * the decoder handles blending frames, so a simple * sequential client does not need this. * * Note that this may differ from whether the composed frame (that is, the * resulting image after blending) has alpha. If this frame does not fill the * entire image dimensions (see {@link AImageDecoderFrameInfo_getFrameRect}) * or it blends with an opaque frame, for example, the composed frame’s alpha * may not match. * * Errors: * - returns false if |info| is null. */ Loading
libs/binder/Android.bp +1 −1 Original line number Diff line number Diff line Loading @@ -112,7 +112,7 @@ cc_library { "PersistableBundle.cpp", "ProcessState.cpp", "RpcAddress.cpp", "RpcConnection.cpp", "RpcSession.cpp", "RpcServer.cpp", "RpcState.cpp", "Static.cpp", Loading
libs/binder/BpBinder.cpp +14 −14 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ #include <binder/IPCThreadState.h> #include <binder/IResultReceiver.h> #include <binder/RpcConnection.h> #include <binder/RpcSession.h> #include <binder/Stability.h> #include <cutils/compiler.h> #include <utils/Log.h> Loading Loading @@ -136,15 +136,15 @@ sp<BpBinder> BpBinder::create(int32_t handle) { return sp<BpBinder>::make(BinderHandle{handle}, trackedUid); } sp<BpBinder> BpBinder::create(const sp<RpcConnection>& connection, const RpcAddress& address) { LOG_ALWAYS_FATAL_IF(connection == nullptr, "BpBinder::create null connection"); sp<BpBinder> BpBinder::create(const sp<RpcSession>& session, const RpcAddress& address) { LOG_ALWAYS_FATAL_IF(session == nullptr, "BpBinder::create null session"); // These are not currently tracked, since there is no UID or other // identifier to track them with. However, if similar functionality is // needed, connection objects keep track of all BpBinder objects on a // per-connection basis. // needed, session objects keep track of all BpBinder objects on a // per-session basis. return sp<BpBinder>::make(SocketHandle{connection, address}); return sp<BpBinder>::make(RpcHandle{session, address}); } BpBinder::BpBinder(Handle&& handle) Loading @@ -165,20 +165,20 @@ BpBinder::BpBinder(BinderHandle&& handle, int32_t trackedUid) : BpBinder(Handle( IPCThreadState::self()->incWeakHandle(this->binderHandle(), this); } BpBinder::BpBinder(SocketHandle&& handle) : BpBinder(Handle(handle)) { LOG_ALWAYS_FATAL_IF(rpcConnection() == nullptr, "BpBinder created w/o connection object"); BpBinder::BpBinder(RpcHandle&& handle) : BpBinder(Handle(handle)) { LOG_ALWAYS_FATAL_IF(rpcSession() == nullptr, "BpBinder created w/o session object"); } bool BpBinder::isRpcBinder() const { return std::holds_alternative<SocketHandle>(mHandle); return std::holds_alternative<RpcHandle>(mHandle); } const RpcAddress& BpBinder::rpcAddress() const { return std::get<SocketHandle>(mHandle).address; return std::get<RpcHandle>(mHandle).address; } const sp<RpcConnection>& BpBinder::rpcConnection() const { return std::get<SocketHandle>(mHandle).connection; const sp<RpcSession>& BpBinder::rpcSession() const { return std::get<RpcHandle>(mHandle).session; } int32_t BpBinder::binderHandle() const { Loading Loading @@ -273,7 +273,7 @@ status_t BpBinder::transact( status_t status; if (CC_UNLIKELY(isRpcBinder())) { status = rpcConnection()->transact(rpcAddress(), code, data, reply, flags); status = rpcSession()->transact(rpcAddress(), code, data, reply, flags); } else { status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags); } Loading Loading @@ -479,7 +479,7 @@ void BpBinder::onLastStrongRef(const void* /*id*/) { ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, binderHandle()); if (CC_UNLIKELY(isRpcBinder())) { (void)rpcConnection()->sendDecStrong(rpcAddress()); (void)rpcSession()->sendDecStrong(rpcAddress()); return; } IF_ALOGV() { Loading
libs/binder/Parcel.cpp +9 −10 Original line number Diff line number Diff line Loading @@ -202,7 +202,7 @@ status_t Parcel::flattenBinder(const sp<IBinder>& binder) status_t status = writeInt32(1); // non-null if (status != OK) return status; RpcAddress address = RpcAddress::zero(); status = mConnection->state()->onBinderLeaving(mConnection, binder, &address); status = mSession->state()->onBinderLeaving(mSession, binder, &address); if (status != OK) return status; status = address.writeToParcel(this); if (status != OK) return status; Loading Loading @@ -273,8 +273,7 @@ status_t Parcel::flattenBinder(const sp<IBinder>& binder) status_t Parcel::unflattenBinder(sp<IBinder>* out) const { if (isForRpc()) { LOG_ALWAYS_FATAL_IF(mConnection == nullptr, "RpcConnection required to read from remote parcel"); LOG_ALWAYS_FATAL_IF(mSession == nullptr, "RpcSession required to read from remote parcel"); int32_t isNull; status_t status = readInt32(&isNull); Loading @@ -286,7 +285,7 @@ status_t Parcel::unflattenBinder(sp<IBinder>* out) const auto addr = RpcAddress::zero(); status_t status = addr.readFromParcel(*this); if (status != OK) return status; binder = mConnection->state()->onBinderEntering(mConnection, addr); binder = mSession->state()->onBinderEntering(mSession, addr); } return finishUnflattenBinder(binder, out); Loading Loading @@ -568,20 +567,20 @@ void Parcel::markForBinder(const sp<IBinder>& binder) { LOG_ALWAYS_FATAL_IF(mData != nullptr, "format must be set before data is written"); if (binder && binder->remoteBinder() && binder->remoteBinder()->isRpcBinder()) { markForRpc(binder->remoteBinder()->getPrivateAccessorForId().rpcConnection()); markForRpc(binder->remoteBinder()->getPrivateAccessorForId().rpcSession()); } } void Parcel::markForRpc(const sp<RpcConnection>& connection) { void Parcel::markForRpc(const sp<RpcSession>& session) { LOG_ALWAYS_FATAL_IF(mData != nullptr && mOwner == nullptr, "format must be set before data is written OR on IPC data"); LOG_ALWAYS_FATAL_IF(connection == nullptr, "markForRpc requires connection"); mConnection = connection; LOG_ALWAYS_FATAL_IF(session == nullptr, "markForRpc requires session"); mSession = session; } bool Parcel::isForRpc() const { return mConnection != nullptr; return mSession != nullptr; } void Parcel::updateWorkSourceRequestHeaderPosition() const { Loading Loading @@ -2499,7 +2498,7 @@ void Parcel::initState() mDataPos = 0; ALOGV("initState Setting data size of %p to %zu", this, mDataSize); ALOGV("initState Setting data pos of %p to %zu", this, mDataPos); mConnection = nullptr; mSession = nullptr; mObjects = nullptr; mObjectsSize = 0; mObjectsCapacity = 0; Loading
libs/binder/RpcServer.cpp +17 −17 Original line number Diff line number Diff line Loading @@ -149,38 +149,38 @@ void RpcServer::join() { { std::lock_guard<std::mutex> _l(mLock); sp<RpcConnection> connection; if (id == RPC_CONNECTION_ID_NEW) { sp<RpcSession> session; if (id == RPC_SESSION_ID_NEW) { // new client! LOG_ALWAYS_FATAL_IF(mConnectionIdCounter >= INT32_MAX, "Out of connection IDs"); mConnectionIdCounter++; LOG_ALWAYS_FATAL_IF(mSessionIdCounter >= INT32_MAX, "Out of session IDs"); mSessionIdCounter++; connection = RpcConnection::make(); connection->setForServer(wp<RpcServer>::fromExisting(this), mConnectionIdCounter); session = RpcSession::make(); session->setForServer(wp<RpcServer>::fromExisting(this), mSessionIdCounter); mConnections[mConnectionIdCounter] = connection; mSessions[mSessionIdCounter] = session; } else { auto it = mConnections.find(id); if (it == mConnections.end()) { ALOGE("Cannot add thread, no record of connection with ID %d", id); auto it = mSessions.find(id); if (it == mSessions.end()) { ALOGE("Cannot add thread, no record of session with ID %d", id); continue; } connection = it->second; session = it->second; } connection->startThread(std::move(clientFd)); session->startThread(std::move(clientFd)); } } } std::vector<sp<RpcConnection>> RpcServer::listConnections() { std::vector<sp<RpcSession>> RpcServer::listSessions() { std::lock_guard<std::mutex> _l(mLock); std::vector<sp<RpcConnection>> connections; for (auto& [id, connection] : mConnections) { std::vector<sp<RpcSession>> sessions; for (auto& [id, session] : mSessions) { (void)id; connections.push_back(connection); sessions.push_back(session); } return connections; return sessions; } bool RpcServer::setupSocketServer(const RpcSocketAddress& addr) { Loading