Merge "Update for modified CapturedStderr."
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 30c5b6a..6cfdb2b 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1290,6 +1290,8 @@
DumpPacketStats();
+ RunDumpsys("EBPF MAP STATS", {"netd", "trafficcontroller"});
+
DoKmsg();
DumpIpAddrAndRules();
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 0fd2dd4..03a411d 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -1692,15 +1692,12 @@
*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 bb6fab3..0db11e1 100644
--- a/cmds/installd/dexopt.h
+++ b/cmds/installd/dexopt.h
@@ -31,7 +31,6 @@
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/ndk/AIBinder.cpp b/libs/binder/ndk/AIBinder.cpp
index d0ce98d..58cbf56 100644
--- a/libs/binder/ndk/AIBinder.cpp
+++ b/libs/binder/ndk/AIBinder.cpp
@@ -28,14 +28,29 @@
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 @@
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;
+ return false;
}
- // 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;
- }
-
- // 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 @@
}
}
-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 @@
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;
}
@@ -200,23 +227,12 @@
return binder->getStrongCount();
}
-void AIBinder_associateClass(AIBinder** binder, const AIBinder_Class* clazz) {
- if (binder == nullptr || *binder == nullptr) {
- return;
+bool AIBinder_associateClass(AIBinder* binder, const AIBinder_Class* clazz) {
+ if (binder == nullptr) {
+ return false;
}
- 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());
- }
- AIBinder_decStrong(*binder);
-
- *binder = result.get(); // Maybe no-op
+ return binder->associateClass(clazz);
}
const AIBinder_Class* AIBinder_getClass(AIBinder* binder) {
diff --git a/libs/binder/ndk/AIBinder_internal.h b/libs/binder/ndk/AIBinder_internal.h
index d44b937..23949bb 100644
--- a/libs/binder/ndk/AIBinder_internal.h
+++ b/libs/binder/ndk/AIBinder_internal.h
@@ -35,23 +35,16 @@
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 @@
// 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 @@
::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 @@
// 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 b63b138..f39e732 100644
--- a/libs/binder/ndk/AParcel.cpp
+++ b/libs/binder/ndk/AParcel.cpp
@@ -34,8 +34,9 @@
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 +45,9 @@
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 f61b914..3979945 100644
--- a/libs/binder/ndk/AServiceManager.cpp
+++ b/libs/binder/ndk/AServiceManager.cpp
@@ -41,7 +41,7 @@
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 23136a2..f752008 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -144,7 +144,7 @@
/**
* If this is hosted in a process other than the current one.
*/
-bool AIBinder_isRemote(AIBinder* binder);
+bool AIBinder_isRemote(const AIBinder* binder);
/**
* This can only be called if a strong reference to this object already exists in process.
@@ -167,11 +167,10 @@
* 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.
@@ -236,7 +235,7 @@
/*
* 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/test/iface.cpp b/libs/binder/ndk/test/iface.cpp
index eed09f0..27553c8 100644
--- a/libs/binder/ndk/test/iface.cpp
+++ b/libs/binder/ndk/test/iface.cpp
@@ -91,7 +91,7 @@
};
IFoo::~IFoo() {
- AIBinder_Weak_delete(mWeakBinder);
+ AIBinder_Weak_delete(&mWeakBinder);
}
binder_status_t IFoo::addService(const char* instance) {
@@ -105,7 +105,7 @@
// 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 +118,15 @@
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;