diff options
| -rw-r--r-- | PREUPLOAD.cfg | 3 | ||||
| -rw-r--r-- | cmds/installd/OWNERS | 7 | ||||
| -rw-r--r-- | cmds/installd/dexopt.cpp | 7 | ||||
| -rw-r--r-- | cmds/installd/dexopt.h | 1 | ||||
| -rw-r--r-- | libs/binder/BufferedTextOutput.cpp | 2 | ||||
| -rw-r--r-- | libs/binder/ndk/AIBinder.cpp | 180 | ||||
| -rw-r--r-- | libs/binder/ndk/AIBinder_internal.h | 27 | ||||
| -rw-r--r-- | libs/binder/ndk/AParcel.cpp | 19 | ||||
| -rw-r--r-- | libs/binder/ndk/AServiceManager.cpp | 6 | ||||
| -rw-r--r-- | libs/binder/ndk/include_ndk/android/binder_ibinder.h | 52 | ||||
| -rw-r--r-- | libs/binder/ndk/include_ndk/android/binder_parcel.h | 5 | ||||
| -rw-r--r-- | libs/binder/ndk/test/iface.cpp | 14 | ||||
| -rw-r--r-- | libs/binder/ndk/test/main_client.cpp | 4 | ||||
| -rw-r--r-- | libs/binder/tests/binderTextOutputTest.cpp | 27 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferLayer.cpp | 3 | ||||
| -rw-r--r-- | services/surfaceflinger/ColorLayer.cpp | 3 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 6 |
17 files changed, 208 insertions, 158 deletions
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg new file mode 100644 index 0000000000..f8f02658fb --- /dev/null +++ b/PREUPLOAD.cfg @@ -0,0 +1,3 @@ +[Hook Scripts] +owners_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "OWNERS$" +installd_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "^cmds/installd/" diff --git a/cmds/installd/OWNERS b/cmds/installd/OWNERS new file mode 100644 index 0000000000..50440f1dae --- /dev/null +++ b/cmds/installd/OWNERS @@ -0,0 +1,7 @@ +set noparent + +calin@google.com +agampe@google.com +jsharkey@android.com +toddke@google.com +ngeoffray@google.com diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp index 0fd2dd4afd..03a411d849 100644 --- a/cmds/installd/dexopt.cpp +++ b/cmds/installd/dexopt.cpp @@ -1692,15 +1692,12 @@ static bool process_secondary_dexoptanalyzer_result(const std::string& dex_path, *dexopt_needed_out = NO_DEXOPT_NEEDED; return true; case 1: // dexoptanalyzer: dex2oat_from_scratch *dexopt_needed_out = DEX2OAT_FROM_SCRATCH; return true; - case 5: // dexoptanalyzer: dex2oat_for_bootimage_odex + case 4: // dexoptanalyzer: dex2oat_for_bootimage_odex *dexopt_needed_out = -DEX2OAT_FOR_BOOT_IMAGE; return true; - case 6: // dexoptanalyzer: dex2oat_for_filter_odex + case 5: // dexoptanalyzer: dex2oat_for_filter_odex *dexopt_needed_out = -DEX2OAT_FOR_FILTER; return true; - case 7: // dexoptanalyzer: dex2oat_for_relocation_odex - *dexopt_needed_out = -DEX2OAT_FOR_RELOCATION; return true; case 2: // dexoptanalyzer: dex2oat_for_bootimage_oat case 3: // dexoptanalyzer: dex2oat_for_filter_oat - case 4: // dexoptanalyzer: dex2oat_for_relocation_oat *error_msg = StringPrintf("Dexoptanalyzer return the status of an oat file." " Expected odex file status for secondary dex %s" " : dexoptanalyzer result=%d", diff --git a/cmds/installd/dexopt.h b/cmds/installd/dexopt.h index bb6fab311b..0db11e1e7b 100644 --- a/cmds/installd/dexopt.h +++ b/cmds/installd/dexopt.h @@ -31,7 +31,6 @@ static constexpr int NO_DEXOPT_NEEDED = 0; static constexpr int DEX2OAT_FROM_SCRATCH = 1; static constexpr int DEX2OAT_FOR_BOOT_IMAGE = 2; static constexpr int DEX2OAT_FOR_FILTER = 3; -static constexpr int DEX2OAT_FOR_RELOCATION = 4; // Clear the reference profile identified by the given profile name. bool clear_primary_reference_profile(const std::string& pkgname, const std::string& profile_name); diff --git a/libs/binder/BufferedTextOutput.cpp b/libs/binder/BufferedTextOutput.cpp index d516eb1d54..857bbf9510 100644 --- a/libs/binder/BufferedTextOutput.cpp +++ b/libs/binder/BufferedTextOutput.cpp @@ -189,7 +189,7 @@ status_t BufferedTextOutput::print(const char* txt, size_t len) // them out without going through the buffer. // Slurp up all of the lines. - const char* lastLine = txt+1; + const char* lastLine = txt; while (txt < end) { if (*txt++ == '\n') lastLine = txt; } diff --git a/libs/binder/ndk/AIBinder.cpp b/libs/binder/ndk/AIBinder.cpp index d0ce98db93..2219f8ea00 100644 --- a/libs/binder/ndk/AIBinder.cpp +++ b/libs/binder/ndk/AIBinder.cpp @@ -28,14 +28,29 @@ using ::android::sp; using ::android::String16; using ::android::wp; +namespace ABBinderTag { + +static const void* kId = "ABBinder"; +static void* kValue = static_cast<void*>(new bool{true}); +void cleanId(const void* /*id*/, void* /*obj*/, void* /*cookie*/){/* do nothing */}; + +static void attach(const sp<IBinder>& binder) { + binder->attachObject(kId, kValue, nullptr /*cookie*/, cleanId); +} +static bool has(const sp<IBinder>& binder) { + return binder != nullptr && binder->findObject(kId) == kValue; +} + +} // namespace ABBinderTag + AIBinder::AIBinder(const AIBinder_Class* clazz) : mClazz(clazz) {} AIBinder::~AIBinder() {} -sp<AIBinder> AIBinder::associateClass(const AIBinder_Class* clazz) { +bool AIBinder::associateClass(const AIBinder_Class* clazz) { using ::android::String8; - if (clazz == nullptr) return nullptr; - if (mClazz == clazz) return this; + if (clazz == nullptr) return false; + if (mClazz == clazz) return true; String8 newDescriptor(clazz->getInterfaceDescriptor()); @@ -45,42 +60,31 @@ sp<AIBinder> AIBinder::associateClass(const AIBinder_Class* clazz) { LOG(ERROR) << __func__ << ": Class descriptors '" << currentDescriptor << "' match during associateClass, but they are different class objects. " "Class descriptor collision?"; - return nullptr; + } else { + LOG(ERROR) << __func__ + << ": Class cannot be associated on object which already has a class. " + "Trying to associate to '" + << newDescriptor.c_str() << "' but already set to '" + << currentDescriptor.c_str() << "'."; } - LOG(ERROR) << __func__ - << ": Class cannot be associated on object which already has a class. Trying to " - "associate to '" - << newDescriptor.c_str() << "' but already set to '" << currentDescriptor.c_str() - << "'."; - return nullptr; + // always a failure because we know mClazz != clazz + return false; } + CHECK(asABpBinder() != nullptr); // ABBinder always has a descriptor + String8 descriptor(getBinder()->getInterfaceDescriptor()); if (descriptor != newDescriptor) { LOG(ERROR) << __func__ << ": Expecting binder to have class '" << newDescriptor.c_str() << "' but descriptor is actually '" << descriptor.c_str() << "'."; - return nullptr; - } - - // The descriptor matches, so if it is local, this is guaranteed to be the libbinder_ndk class. - // An error here can occur if there is a conflict between descriptors (two unrelated classes - // define the same descriptor), but this should never happen. - - // if this is a local ABBinder, mClazz should be non-null - CHECK(asABBinder() == nullptr); - CHECK(asABpBinder() != nullptr); - - if (!isRemote()) { - // ABpBinder but proxy to a local object. Therefore that local object must be an ABBinder. - ABBinder* binder = static_cast<ABBinder*>(getBinder().get()); - return binder; + return false; } - // This is a remote object + // if this is a local object, it's not one known to libbinder_ndk mClazz = clazz; - return this; + return true; } ABBinder::ABBinder(const AIBinder_Class* clazz, void* userData) @@ -111,24 +115,45 @@ binder_status_t ABBinder::onTransact(transaction_code_t code, const Parcel& data } } -ABpBinder::ABpBinder(::android::sp<::android::IBinder> binder) +ABpBinder::ABpBinder(const ::android::sp<::android::IBinder>& binder) : AIBinder(nullptr /*clazz*/), BpRefBase(binder) { CHECK(binder != nullptr); } ABpBinder::~ABpBinder() {} +sp<AIBinder> ABpBinder::fromBinder(const ::android::sp<::android::IBinder>& binder) { + if (binder == nullptr) { + return nullptr; + } + if (ABBinderTag::has(binder)) { + return static_cast<ABBinder*>(binder.get()); + } + return new ABpBinder(binder); +} + struct AIBinder_Weak { wp<AIBinder> binder; }; AIBinder_Weak* AIBinder_Weak_new(AIBinder* binder) { - if (binder == nullptr) return nullptr; + if (binder == nullptr) { + return nullptr; + } + return new AIBinder_Weak{wp<AIBinder>(binder)}; } -void AIBinder_Weak_delete(AIBinder_Weak* weakBinder) { - delete weakBinder; +void AIBinder_Weak_delete(AIBinder_Weak** weakBinder) { + if (weakBinder == nullptr) { + return; + } + + delete *weakBinder; + *weakBinder = nullptr; } AIBinder* AIBinder_Weak_promote(AIBinder_Weak* weakBinder) { - if (weakBinder == nullptr) return nullptr; + if (weakBinder == nullptr) { + return nullptr; + } + sp<AIBinder> binder = weakBinder->binder.promote(); AIBinder_incStrong(binder.get()); return binder.get(); @@ -162,12 +187,14 @@ AIBinder* AIBinder_new(const AIBinder_Class* clazz, void* args) { void* userData = clazz->onCreate(args); - AIBinder* ret = new ABBinder(clazz, userData); - AIBinder_incStrong(ret); - return ret; + sp<AIBinder> ret = new ABBinder(clazz, userData); + ABBinderTag::attach(ret->getBinder()); + + AIBinder_incStrong(ret.get()); + return ret.get(); } -bool AIBinder_isRemote(AIBinder* binder) { +bool AIBinder_isRemote(const AIBinder* binder) { if (binder == nullptr) { return true; } @@ -175,6 +202,22 @@ bool AIBinder_isRemote(AIBinder* binder) { return binder->isRemote(); } +bool AIBinder_isAlive(const AIBinder* binder) { + if (binder == nullptr) { + return false; + } + + return const_cast<AIBinder*>(binder)->getBinder()->isBinderAlive(); +} + +binder_status_t AIBinder_ping(AIBinder* binder) { + if (binder == nullptr) { + return EX_NULL_POINTER; + } + + return binder->getBinder()->pingBinder(); +} + void AIBinder_incStrong(AIBinder* binder) { if (binder == nullptr) { LOG(ERROR) << __func__ << ": on null binder"; @@ -200,23 +243,12 @@ int32_t AIBinder_debugGetRefCount(AIBinder* binder) { return binder->getStrongCount(); } -void AIBinder_associateClass(AIBinder** binder, const AIBinder_Class* clazz) { - if (binder == nullptr || *binder == nullptr) { - return; - } - - sp<AIBinder> result = (*binder)->associateClass(clazz); - - // This function takes one refcount of 'binder' and delivers one refcount of 'result' to the - // callee. First we give the callee their refcount and then take it away from binder. This is - // done in this order in order to handle the case that the result and the binder are the same - // object. - if (result != nullptr) { - AIBinder_incStrong(result.get()); +bool AIBinder_associateClass(AIBinder* binder, const AIBinder_Class* clazz) { + if (binder == nullptr) { + return false; } - AIBinder_decStrong(*binder); - *binder = result.get(); // Maybe no-op + return binder->associateClass(clazz); } const AIBinder_Class* AIBinder_getClass(AIBinder* binder) { @@ -253,6 +285,13 @@ binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in) { return EX_ILLEGAL_STATE; } + if (!binder->isRemote()) { + LOG(WARNING) << "A binder object at " << binder + << " is being transacted on, however, this object is in the same process as " + "its proxy. Transacting with this binder is expensive compared to just " + "calling the corresponding functionality in the same process."; + } + *in = new AParcel(binder); binder_status_t status = (**in)->writeInterfaceToken(clazz->getInterfaceDescriptor()); if (status != EX_NONE) { @@ -263,12 +302,6 @@ binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in) { return status; } -using AutoParcelDestroyer = std::unique_ptr<AParcel*, void (*)(AParcel**)>; -static void destroy_parcel(AParcel** parcel) { - delete *parcel; - *parcel = nullptr; -} - binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, AParcel** in, AParcel** out, binder_flags_t flags) { if (in == nullptr) { @@ -276,9 +309,10 @@ binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, APa return EX_NULL_POINTER; } + using AutoParcelDestroyer = std::unique_ptr<AParcel*, void (*)(AParcel**)>; // This object is the input to the transaction. This function takes ownership of it and deletes // it. - AutoParcelDestroyer forIn(in, destroy_parcel); + AutoParcelDestroyer forIn(in, AParcel_delete); if (!isUserCommand(code)) { LOG(ERROR) << __func__ << ": Only user-defined transactions can be made from the NDK."; @@ -313,33 +347,3 @@ binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, APa return parcelStatus; } - -binder_status_t AIBinder_finalizeTransaction(AIBinder* binder, AParcel** out) { - if (out == nullptr) { - LOG(ERROR) << __func__ << ": requires non-null out parameter"; - return EX_NULL_POINTER; - } - - // This object is the input to the transaction. This function takes ownership of it and deletes - // it. - AutoParcelDestroyer forOut(out, destroy_parcel); - - if (binder == nullptr || *out == nullptr) { - LOG(ERROR) << __func__ << ": requires non-null parameters."; - return EX_NULL_POINTER; - } - - if ((*out)->getBinder() != binder) { - LOG(ERROR) << __func__ << ": parcel is associated with binder object " << binder - << " but called with " << (*out)->getBinder(); - return EX_ILLEGAL_STATE; - } - - if ((**out)->dataAvail() != 0) { - LOG(ERROR) << __func__ - << ": Only part of this transaction was read. There is remaining data left."; - return EX_ILLEGAL_STATE; - } - - return EX_NONE; -} diff --git a/libs/binder/ndk/AIBinder_internal.h b/libs/binder/ndk/AIBinder_internal.h index d44b937ec7..23949bb034 100644 --- a/libs/binder/ndk/AIBinder_internal.h +++ b/libs/binder/ndk/AIBinder_internal.h @@ -35,23 +35,16 @@ struct AIBinder : public virtual ::android::RefBase { AIBinder(const AIBinder_Class* clazz); virtual ~AIBinder(); - // This returns an AIBinder object with this class associated. If the class is already - // associated, 'this' will be returned. If there is a local AIBinder implementation, that will - // be returned. If this is a remote object, the class will be associated and this will be ready - // to be used for transactions. - ::android::sp<AIBinder> associateClass(const AIBinder_Class* clazz); + bool associateClass(const AIBinder_Class* clazz); const AIBinder_Class* getClass() const { return mClazz; } - // This does not create the binder if it does not exist in the process. virtual ::android::sp<::android::IBinder> getBinder() = 0; virtual ABBinder* asABBinder() { return nullptr; } virtual ABpBinder* asABpBinder() { return nullptr; } - bool isRemote() { - auto binder = getBinder(); - // if the binder is nullptr, then it is a local object which hasn't been sent out of process - // yet. - return binder != nullptr && binder->remoteBinder() != nullptr; + bool isRemote() const { + ::android::sp<::android::IBinder> binder = const_cast<AIBinder*>(this)->getBinder(); + return binder->remoteBinder() != nullptr; } private: @@ -63,7 +56,6 @@ private: // This is a local AIBinder object with a known class. struct ABBinder : public AIBinder, public ::android::BBinder { - ABBinder(const AIBinder_Class* clazz, void* userData); virtual ~ABBinder(); void* getUserData() { return mUserData; } @@ -76,6 +68,11 @@ struct ABBinder : public AIBinder, public ::android::BBinder { ::android::Parcel* reply, binder_flags_t flags) override; private: + ABBinder(const AIBinder_Class* clazz, void* userData); + + // only thing that should create an ABBinder + friend AIBinder* AIBinder_new(const AIBinder_Class*, void*); + // Can contain implementation if this is a local binder. This can still be nullptr for a local // binder. If it is nullptr, the implication is the implementation state is entirely external to // this object and the functionality provided in the AIBinder_Class is sufficient. @@ -85,11 +82,15 @@ private: // This binder object may be remote or local (even though it is 'Bp'). It is not yet associated with // a class. struct ABpBinder : public AIBinder, public ::android::BpRefBase { - ABpBinder(::android::sp<::android::IBinder> binder); + static ::android::sp<AIBinder> fromBinder(const ::android::sp<::android::IBinder>& binder); + virtual ~ABpBinder(); ::android::sp<::android::IBinder> getBinder() override { return remote(); } ABpBinder* asABpBinder() override { return this; } + +private: + ABpBinder(const ::android::sp<::android::IBinder>& binder); }; struct AIBinder_Class { diff --git a/libs/binder/ndk/AParcel.cpp b/libs/binder/ndk/AParcel.cpp index b63b138dc4..93384d64fa 100644 --- a/libs/binder/ndk/AParcel.cpp +++ b/libs/binder/ndk/AParcel.cpp @@ -25,6 +25,15 @@ using ::android::IBinder; using ::android::Parcel; using ::android::sp; +void AParcel_delete(AParcel** parcel) { + if (parcel == nullptr) { + return; + } + + delete *parcel; + *parcel = nullptr; +} + binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder) { return (*parcel)->writeStrongBinder(binder->getBinder()); } @@ -34,8 +43,9 @@ binder_status_t AParcel_readStrongBinder(const AParcel* parcel, AIBinder** binde if (status != EX_NONE) { return status; } - *binder = new ABpBinder(readBinder); - AIBinder_incStrong(*binder); + sp<AIBinder> ret = ABpBinder::fromBinder(readBinder); + AIBinder_incStrong(ret.get()); + *binder = ret.get(); return status; } binder_status_t AParcel_readNullableStrongBinder(const AParcel* parcel, AIBinder** binder) { @@ -44,8 +54,9 @@ binder_status_t AParcel_readNullableStrongBinder(const AParcel* parcel, AIBinder if (status != EX_NONE) { return status; } - *binder = new ABpBinder(readBinder); - AIBinder_incStrong(*binder); + sp<AIBinder> ret = ABpBinder::fromBinder(readBinder); + AIBinder_incStrong(ret.get()); + *binder = ret.get(); return status; } diff --git a/libs/binder/ndk/AServiceManager.cpp b/libs/binder/ndk/AServiceManager.cpp index f61b914089..3979945e45 100644 --- a/libs/binder/ndk/AServiceManager.cpp +++ b/libs/binder/ndk/AServiceManager.cpp @@ -41,7 +41,7 @@ AIBinder* AServiceManager_getService(const char* instance) { sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> binder = sm->getService(String16(instance)); - AIBinder* ret = new ABpBinder(binder); - AIBinder_incStrong(ret); - return ret; + sp<AIBinder> ret = ABpBinder::fromBinder(binder); + AIBinder_incStrong(ret.get()); + return ret.get(); } diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h index 0bd4b8c6a1..65bc5a5b07 100644 --- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h +++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h @@ -154,7 +154,23 @@ __attribute__((warn_unused_result)) AIBinder* AIBinder_new(const AIBinder_Class* /** * If this is hosted in a process other than the current one. */ -bool AIBinder_isRemote(AIBinder* binder); +bool AIBinder_isRemote(const AIBinder* binder); + +/** + * If this binder is known to be alive. This will not send a transaction to a remote process and + * returns a result based on the last known information. That is, whenever a transaction is made, + * this is automatically updated to reflect the current alive status of this binder. This will be + * updated as the result of a transaction made using AIBinder_transact, but it will also be updated + * based on the results of bookkeeping or other transactions made internally. + */ +bool AIBinder_isAlive(const AIBinder* binder); + +/** + * Built-in transaction for all binder objects. This sends a transaction which will immediately + * return. Usually this is used to make sure that a binder is alive, as a placeholder call, or as a + * sanity check. + */ +binder_status_t AIBinder_ping(AIBinder* binder); /** * This can only be called if a strong reference to this object already exists in process. @@ -177,13 +193,12 @@ int32_t AIBinder_debugGetRefCount(AIBinder* binder); * However, if an object is just intended to be passed through to another process or used as a * handle this need not be called. * - * The binder parameter may or may not be updated. If it is updated, the ownership of the original - * object is transferred to the new object. If the class association fails, ownership of the binder - * is lost, and it is set to nullptr. + * This returns true if the class association succeeds. If it fails, no change is made to the + * binder object. */ -void AIBinder_associateClass(AIBinder** binder, const AIBinder_Class* clazz); +bool AIBinder_associateClass(AIBinder* binder, const AIBinder_Class* clazz); -/* +/** * Returns the class that this binder was constructed with or associated with. */ const AIBinder_Class* AIBinder_getClass(AIBinder* binder); @@ -197,10 +212,9 @@ void* AIBinder_getUserData(AIBinder* binder); /** * A transaction is a series of calls to these functions which looks this * - call AIBinder_prepareTransaction - * - fill out parcel with in parameters (lifetime of the 'in' variable) + * - fill out the in parcel with parameters (lifetime of the 'in' variable) * - call AIBinder_transact - * - fill out parcel with out parameters (lifetime of the 'out' variable) - * - call AIBinder_finalizeTransaction + * - read results from the out parcel (lifetime of the 'out' variable) */ /** @@ -211,7 +225,10 @@ void* AIBinder_getUserData(AIBinder* binder); * can be avoided. This AIBinder must be either built with a class or associated with a class before * using this API. * - * This does not affect the ownership of binder. + * This does not affect the ownership of binder. When this function succeeds, the in parcel's + * ownership is passed to the caller. At this point, the parcel can be filled out and passed to + * AIBinder_transact. Alternatively, if there is an error while filling out the parcel, it can be + * deleted with AParcel_delete. */ binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in); @@ -224,29 +241,22 @@ binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in); * remote process has processed the transaction, and the out parcel will contain the output data * from transaction. * - * This does not affect the ownership of binder. + * This does not affect the ownership of binder. The out parcel's ownership is passed to the caller + * and must be released with AParcel_delete when finished reading. */ binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, AParcel** in, AParcel** out, binder_flags_t flags); /** - * This takes ownership of the out parcel and automatically deletes it. Additional checks for - * security or debugging maybe performed internally. - * - * This does not affect the ownership of binder. - */ -binder_status_t AIBinder_finalizeTransaction(AIBinder* binder, AParcel** out); - -/* * This does not take any ownership of the input binder, but it can be used to retrieve it if * something else in some process still holds a reference to it. */ __attribute__((warn_unused_result)) AIBinder_Weak* AIBinder_Weak_new(AIBinder* binder); -/* +/** * Deletes the weak reference. This will have no impact on the lifetime of the binder. */ -void AIBinder_Weak_delete(AIBinder_Weak* weakBinder); +void AIBinder_Weak_delete(AIBinder_Weak** weakBinder); /** * If promotion succeeds, result will have one strong refcount added to it. Otherwise, this returns diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel.h b/libs/binder/ndk/include_ndk/android/binder_parcel.h index 75ac4ffac7..e871ed12b1 100644 --- a/libs/binder/ndk/include_ndk/android/binder_parcel.h +++ b/libs/binder/ndk/include_ndk/android/binder_parcel.h @@ -45,6 +45,11 @@ struct AParcel; typedef struct AParcel AParcel; /** + * Cleans up a parcel and sets it to nullptr. + */ +void AParcel_delete(AParcel** parcel); + +/** * Writes an AIBinder to the next location in a non-null parcel. Can be null. */ binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder); diff --git a/libs/binder/ndk/test/iface.cpp b/libs/binder/ndk/test/iface.cpp index eed09f02c7..a1aa0fabc4 100644 --- a/libs/binder/ndk/test/iface.cpp +++ b/libs/binder/ndk/test/iface.cpp @@ -81,7 +81,8 @@ public: int32_t out; CHECK(EX_NONE == AParcel_readInt32(parcelOut, &out)); - CHECK(EX_NONE == AIBinder_finalizeTransaction(mBinder, &parcelOut)); + AParcel_delete(&parcelOut); + return out; } @@ -91,7 +92,7 @@ private: }; IFoo::~IFoo() { - AIBinder_Weak_delete(mWeakBinder); + AIBinder_Weak_delete(&mWeakBinder); } binder_status_t IFoo::addService(const char* instance) { @@ -105,7 +106,7 @@ binder_status_t IFoo::addService(const char* instance) { // or one strong refcount here binder = AIBinder_new(IFoo::kClass, static_cast<void*>(new IFoo_Class_Data{this})); if (mWeakBinder != nullptr) { - AIBinder_Weak_delete(mWeakBinder); + AIBinder_Weak_delete(&mWeakBinder); } mWeakBinder = AIBinder_Weak_new(binder); } @@ -118,12 +119,15 @@ binder_status_t IFoo::addService(const char* instance) { sp<IFoo> IFoo::getService(const char* instance) { AIBinder* binder = AServiceManager_getService(instance); // maybe nullptr - AIBinder_associateClass(&binder, IFoo::kClass); - if (binder == nullptr) { return nullptr; } + if (!AIBinder_associateClass(binder, IFoo::kClass)) { + AIBinder_decStrong(binder); + return nullptr; + } + if (AIBinder_isRemote(binder)) { sp<IFoo> ret = new BpFoo(binder); // takes ownership of binder return ret; diff --git a/libs/binder/ndk/test/main_client.cpp b/libs/binder/ndk/test/main_client.cpp index 7c53e512fe..967789f140 100644 --- a/libs/binder/ndk/test/main_client.cpp +++ b/libs/binder/ndk/test/main_client.cpp @@ -38,6 +38,10 @@ TEST(NdkBinder, DoubleNumber) { TEST(NdkBinder, RetrieveNonNdkService) { AIBinder* binder = AServiceManager_getService(kExistingNonNdkService); ASSERT_NE(nullptr, binder); + EXPECT_TRUE(AIBinder_isRemote(binder)); + EXPECT_TRUE(AIBinder_isAlive(binder)); + EXPECT_EQ(EX_NONE, AIBinder_ping(binder)); + AIBinder_decStrong(binder); } diff --git a/libs/binder/tests/binderTextOutputTest.cpp b/libs/binder/tests/binderTextOutputTest.cpp index f6dd22d798..ce99f59d7c 100644 --- a/libs/binder/tests/binderTextOutputTest.cpp +++ b/libs/binder/tests/binderTextOutputTest.cpp @@ -28,15 +28,14 @@ #include <binder/TextOutput.h> #include <binder/Debug.h> -static void CheckMessage(const CapturedStderr& cap, +static void CheckMessage(CapturedStderr& cap, const char* expected, bool singleline) { - std::string output; - ASSERT_EQ(0, lseek(cap.fd(), 0, SEEK_SET)); - android::base::ReadFdToString(cap.fd(), &output); + cap.Stop(); + std::string output = cap.str(); if (singleline) output.erase(std::remove(output.begin(), output.end(), '\n')); - ASSERT_STREQ(output.c_str(), expected); + ASSERT_EQ(output, expected); } #define CHECK_LOG_(input, expect, singleline) \ @@ -60,28 +59,22 @@ static void CheckMessage(const CapturedStderr& cap, TEST(TextOutput, HandlesStdEndl) { CapturedStderr cap; android::aerr << "foobar" << std::endl; - std::string output; - ASSERT_EQ(0, lseek(cap.fd(), 0, SEEK_SET)); - android::base::ReadFdToString(cap.fd(), &output); - ASSERT_STREQ(output.c_str(), "foobar\n"); + cap.Stop(); + ASSERT_EQ(cap.str(), "foobar\n"); } TEST(TextOutput, HandlesCEndl) { CapturedStderr cap; android::aerr << "foobar" << "\n"; - std::string output; - ASSERT_EQ(0, lseek(cap.fd(), 0, SEEK_SET)); - android::base::ReadFdToString(cap.fd(), &output); - ASSERT_STREQ(output.c_str(), "foobar\n"); + cap.Stop(); + ASSERT_EQ(cap.str(), "foobar\n"); } TEST(TextOutput, HandlesAndroidEndl) { CapturedStderr cap; android::aerr << "foobar" << android::endl; - std::string output; - ASSERT_EQ(0, lseek(cap.fd(), 0, SEEK_SET)); - android::base::ReadFdToString(cap.fd(), &output); - ASSERT_STREQ(output.c_str(), "foobar\n"); + cap.Stop(); + ASSERT_EQ(cap.str(), "foobar\n"); } TEST(TextOutput, HandleEmptyString) { diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index fda7906744..f04bd17fc9 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -622,6 +622,9 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) const auto& viewport = displayDevice->getViewport(); Region visible = tr.transform(visibleRegion.intersect(viewport)); auto hwcId = displayDevice->getHwcDisplayId(); + if (!hasHwcLayer(hwcId)) { + return; + } auto& hwcInfo = getBE().mHwcLayers[hwcId]; auto& hwcLayer = hwcInfo.layer; auto error = hwcLayer->setVisibleRegion(visible); diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp index 512564c2db..ff957c0ee7 100644 --- a/services/surfaceflinger/ColorLayer.cpp +++ b/services/surfaceflinger/ColorLayer.cpp @@ -66,6 +66,9 @@ void ColorLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) { const auto& viewport = displayDevice->getViewport(); Region visible = tr.transform(visibleRegion.intersect(viewport)); auto hwcId = displayDevice->getHwcDisplayId(); + if (!hasHwcLayer(hwcId)) { + return; + } auto& hwcInfo = getBE().mHwcLayers[hwcId]; auto& hwcLayer = hwcInfo.layer; auto error = hwcLayer->setVisibleRegion(visible); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 2595ec1a05..1dc3f4c693 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -486,6 +486,9 @@ FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const { void Layer::setGeometry(const sp<const DisplayDevice>& displayDevice, uint32_t z) { const auto hwcId = displayDevice->getHwcDisplayId(); + if (!hasHwcLayer(hwcId)) { + return; + } auto& hwcInfo = getBE().mHwcLayers[hwcId]; // enable this layer @@ -1977,6 +1980,9 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) } void Layer::writeToProto(LayerProto* layerInfo, int32_t hwcId) { + if (!hasHwcLayer(hwcId)) { + return; + } writeToProto(layerInfo, LayerVector::StateSet::Drawing); const auto& hwcInfo = getBE().mHwcLayers.at(hwcId); |