status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
- // Once a binder has died, it will never come back to life.
+ // Once a binder has died, it will never come back to life. But
+ // note that the special case of the global service manager cannot
+ // die; there is no guarantee in the framework that it will be
+ // alive before a binder service object is instantiated, so we
+ // ignore errors for that special object so that
+ // IServiceManager::addService() calls can be retried.
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
- if (status == DEAD_OBJECT) mAlive = 0;
+ if (status == DEAD_OBJECT)
+ if (this != ProcessState::self()->getContextObject(NULL).get())
+ mAlive = 0;
return status;
}
-
return DEAD_OBJECT;
}
#include <unistd.h>
+#define ADD_SERVICE_RETRY_SECS 10
+
namespace android {
sp<IServiceManager> defaultServiceManager()
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated)
{
- Parcel data, reply;
- data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
- data.writeString16(name);
- data.writeStrongBinder(service);
- data.writeInt32(allowIsolated ? 1 : 0);
- status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
- return err == NO_ERROR ? reply.readExceptionCode() : err;
+ status_t err;
+ for (int i=0; i<ADD_SERVICE_RETRY_SECS; i++) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
+ data.writeString16(name);
+ data.writeStrongBinder(service);
+ data.writeInt32(allowIsolated ? 1 : 0);
+ err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
+ if (err == NO_ERROR)
+ return reply.readExceptionCode();
+ if (i != ADD_SERVICE_RETRY_SECS) {
+ ALOGI("addService() %s failed (err %d - no service manager yet?). Retrying...\n",
+ String8(name).string(), err);
+ sleep(1);
+ } else {
+ ALOGE("addService() %s failed (err %d). Giving up.\n",
+ String8(name).string(), err);
+ }
+ }
+ return err;
}
virtual Vector<String16> listServices()