-
}
-
return;
-
}
-
case BINDER_TYPE_WEAK_HANDLE: {
-
const wp b = proc->getWeakProxyForHandle(obj.handle);
-
if (b != NULL) b.get_refs()->decWeak(who);
-
return;
-
}
-
case BINDER_TYPE_FD: {
-
if (obj.cookie != (void*)0) close(obj.handle);
-
return;
-
}
-
}
-
LOGE(“Invalid object type 0x%08lx”, obj.type);
-
}
-
inline static status_t finish_flatten_binder(
-
const sp& binder, const flat_binder_object& flat, Parcel* out)
-
{
-
return out->writeObject(flat, false);
-
}
-
status_t flatten_binder(const sp& proc,
-
const sp& binder, Parcel* out)
-
{
-
flat_binder_object obj;
-
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
-
if (binder != NULL) {
-
IBinder *local = binder->localBinder();
-
if (!local) {
-
BpBinder *proxy = binder->remoteBinder();
-
if (proxy == NULL) {
-
LOGE(“null proxy”);
-
}
-
const int32_t handle = proxy ? proxy->handle() : 0;
-
obj.type = BINDER_TYPE_HANDLE;
-
obj.handle = handle;
-
obj.cookie = NULL;
-
} else {
-
obj.type = BINDER_TYPE_BINDER;
-
obj.binder = local->getWeakRefs();
-
obj.cookie = local;
-
}
-
} else {
-
obj.type = BINDER_TYPE_BINDER;
-
obj.binder = NULL;
-
obj.cookie = NULL;
-
}
-
return finish_flatten_binder(binder, obj, out);
-
}
-
status_t flatten_binder(const sp& proc,
-
const wp& binder, Parcel* out)
-
{
-
flat_binder_object obj;
-
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
-
if (binder != NULL) {
-
sp real = binder.promote();
-
if (real != NULL) {
-
IBinder *local = real->localBinder();
-
if (!local) {
-
BpBinder *proxy = real->remoteBinder();
-
if (proxy == NULL) {
-
LOGE(“null proxy”);
-
}
-
const int32_t handle = proxy ? proxy->handle() : 0;
-
obj.type = BINDER_TYPE_WEAK_HANDLE;
-
obj.handle = handle;
-
obj.cookie = NULL;
-
} else {
-
obj.type = BINDER_TYPE_WEAK_BINDER;
-
obj.binder = binder.get_refs();
-
obj.cookie = binder.unsafe_get();
-
}
-
return finish_flatten_binder(real, obj, out);
-
}
-
// XXX How to deal? In order to flatten the given binder,
-
// we need to probe it for information, which requires a primary
-
// reference… but we don’t have one.
-
//
-
// The OpenBinder implementation uses a dynamic_cast<> here,
-
// but we can’t do that with the different reference counting
-
// implementation we are using.
-
LOGE(“Unable to unflatten Binder weak reference!”);
-
obj.type = BINDER_TYPE_BINDER;
-
obj.binder = NULL;
-
obj.cookie = NULL;
-
return finish_flatten_binder(NULL, obj, out);
-
} else {
-
obj.type = BINDER_TYPE_BINDER;
-
obj.binder = NULL;
-
obj.cookie = NULL;
-
return finish_flatten_binder(NULL, obj, out);
-
}
-
}
-
inline static status_t finish_unflatten_binder(
-
BpBinder* proxy, const flat_binder_object& flat, const Parcel& in)
-
{
-
return NO_ERROR;
-
}
-
status_t unflatten_binder(const sp& proc,
-
const Parcel& in, sp* out)
-
{
-
const flat_binder_object* flat = in.readObject(false);
-
if (flat) {
-
switch (flat->type) {
-
case BINDER_TYPE_BINDER:
-
*out = static_cast<IBinder*>(flat->cookie);
-
return finish_unflatten_binder(NULL, *flat, in);
-
case BINDER_TYPE_HANDLE:
-
*out = proc->getStrongProxyForHandle(flat->handle);
-
return finish_unflatten_binder(
-
static_cast<BpBinder*>(out->get()), *flat, in);
-
}
-
}
-
return BAD_TYPE;
-
}
-
status_t unflatten_binder(const sp& proc,
-
const Parcel& in, wp* out)
-
{
-
const flat_binder_object* flat = in.readObject(false);
-
if (flat) {
-
switch (flat->type) {
-
case BINDER_TYPE_BINDER:
-
*out = static_cast<IBinder*>(flat->cookie);
-
return finish_unflatten_binder(NULL, *flat, in);
-
case BINDER_TYPE_WEAK_BINDER:
-
if (flat->binder != NULL) {
-
out->set_object_and_refs(
-
static_cast<IBinder*>(flat->cookie),
-
static_castRefBase::weakref\_type\*(flat->binder));
-
} else {
-
*out = NULL;
-
}
-
return finish_unflatten_binder(NULL, *flat, in);
-
case BINDER_TYPE_HANDLE:
-
case BINDER_TYPE_WEAK_HANDLE:
-
*out = proc->getWeakProxyForHandle(flat->handle);
-
return finish_unflatten_binder(
-
static_cast<BpBinder*>(out->unsafe_get()), *flat, in);
-
}
-
}
-
return BAD_TYPE;
-
}
-
// ---------------------------------------------------------------------------
-
Parcel::Parcel()
-
{
-
initState();
-
}
-
Parcel::~Parcel()
-
{
-
freeDataNoInit();
-
}
-
const uint8_t* Parcel::data() const
-
{
-
return mData;
-
}
-
size_t Parcel::dataSize() const
-
{
-
return (mDataSize > mDataPos ? mDataSize : mDataPos);
-
}
-
size_t Parcel::dataAvail() const
-
{
-
// TODO: decide what to do about the possibility that this can
-
// report an available-data size that exceeds a Java int’s max
-
// positive value, causing havoc. Fortunately this will only
-
// happen if someone constructs a Parcel containing more than two
-
// gigabytes of data, which on typical phone hardware is simply
-
// not possible.
-
return dataSize() - dataPosition();
-
}
-
size_t Parcel::dataPosition() const
-
{
-
return mDataPos;
-
}
-
size_t Parcel::dataCapacity() const
-
{
-
return mDataCapacity;
-
}
-
status_t Parcel::setDataSize(size_t size)
-
{
-
status_t err;
-
err = continueWrite(size);
-
if (err == NO_ERROR) {
-
mDataSize = size;
-
LOGV(“setDataSize Setting data size of %p to %d/n”, this, mDataSize);
-
}
-
return err;
-
}
-
void Parcel::setDataPosition(size_t pos) const
-
{
-
mDataPos = pos;
-
mNextObjectHint = 0;
-
}
-
status_t Parcel::setDataCapacity(size_t size)
-
{
-
if (size > mDataSize) return continueWrite(size);
-
return NO_ERROR;
-
}
-
status_t Parcel::setData(const uint8_t* buffer, size_t len)
-
{
-
status_t err = restartWrite(len);
-
if (err == NO_ERROR) {
-
memcpy(const_cast<uint8_t*>(data()), buffer, len);
-
mDataSize = len;
-
mFdsKnown = false;
-
}
-
return err;
-
}
-
status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len)
-
{
-
const sp proc(ProcessState::self());
-
status_t err;
-
uint8_t *data = parcel->mData;
-
size_t *objects = parcel->mObjects;
-
size_t size = parcel->mObjectsSize;
-
int startPos = mDataPos;
-
int firstIndex = -1, lastIndex = -2;
-
if (len == 0) {
-
return NO_ERROR;
-
}
-
// range checks against the source parcel size
-
if ((offset > parcel->mDataSize)
-
|| (len > parcel->mDataSize)
-
|| (offset + len > parcel->mDataSize)) {
-
return BAD_VALUE;
-
}
-
// Count objects in range
-
for (int i = 0; i < (int) size; i++) {
-
size_t off = objects[i];
-
if ((off >= offset) && (off < offset + len)) {
-
if (firstIndex == -1) {
-
firstIndex = i;
-
}
-
lastIndex = i;
-
}
-
}
-
int numObjects = lastIndex - firstIndex + 1;
-
// grow data
-
err = growData(len);
-
if (err != NO_ERROR) {
-
return err;
-
}
-
// append data
-
memcpy(mData + mDataPos, data + offset, len);
-
mDataPos += len;
-
mDataSize += len;
-
if (numObjects > 0) {
-
// grow objects
-
if (mObjectsCapacity < mObjectsSize + numObjects) {
-
int newSize = ((mObjectsSize + numObjects)*3)/2;
-
size_t *objects =
-
(size_t*)realloc(mObjects, newSize*sizeof(size_t));
-
if (objects == (size_t*)0) {
-
return NO_MEMORY;
-
}
-
mObjects = objects;
-
mObjectsCapacity = newSize;
-
}
-
// append and acquire objects
-
int idx = mObjectsSize;
-
for (int i = firstIndex; i <= lastIndex; i++) {
-
size_t off = objects[i] - offset + startPos;
-
mObjects[idx++] = off;
-
mObjectsSize++;
-
flat_binder_object* flat
-
= reinterpret_cast<flat_binder_object*>(mData + off);
-
acquire_object(proc, *flat, this);
-
if (flat->type == BINDER_TYPE_FD) {
-
// If this is a file descriptor, we need to dup it so the
-
// new Parcel now owns its own fd, and can declare that we
-
// officially know we have fds.
-
flat->handle = dup(flat->handle);
-
flat->cookie = (void*)1;
-
mHasFds = mFdsKnown = true;
-
}
-
}
-
}
-
return NO_ERROR;
-
}
-
bool Parcel::hasFileDescriptors() const
-
{
-
if (!mFdsKnown) {
-
scanForFds();
-
}
-
return mHasFds;
-
}
-
status_t Parcel::writeInterfaceToken(const String16& interface)
-
{
-
// currently the interface identification token is just its name as a string
-
return writeString16(interface);
-
}
-
bool Parcel::checkInterface(IBinder* binder) const
-
{
-
return enforceInterface(binder->getInterfaceDescriptor());
-
}
-
bool Parcel::enforceInterface(const String16& interface) const
-
{
-
const String16 str(readString16());
-
if (str == interface) {
-
return true;
-
} else {
-
LOGW(“**** enforceInterface() expected ‘%s’ but read ‘%s’/n”,
-
String8(interface).string(), String8(str).string());
-
return false;
-
}
-
}
-
const size_t* Parcel::objects() const
-
{
-
return mObjects;
-
}
-
size_t Parcel::objectsCount() const
-
{
-
return mObjectsSize;
-
}
-
status_t Parcel::errorCheck() const
-
{
-
return mError;
-
}
-
void Parcel::setError(status_t err)
-
{
-
mError = err;
-
}
-
status_t Parcel::finishWrite(size_t len)
-
{
-
//printf(“Finish write of %d/n”, len);
-
mDataPos += len;
-
LOGV(“finishWrite Setting data pos of %p to %d/n”, this, mDataPos);
-
if (mDataPos > mDataSize) {
-
mDataSize = mDataPos;
-
LOGV(“finishWrite Setting data size of %p to %d/n”, this, mDataSize);
-
}
-
//printf(“New pos=%d, size=%d/n”, mDataPos, mDataSize);
-
return NO_ERROR;
-
}
-
status_t Parcel::writeUnpadded(const void* data, size_t len)
-
{
-
size_t end = mDataPos + len;
-
if (end < mDataPos) {
-
// integer overflow
-
return BAD_VALUE;
-
}
-
if (end <= mDataCapacity) {
-
restart_write:
-
memcpy(mData+mDataPos, data, len);
-
return finishWrite(len);
-
}
-
status_t err = growData(len);
-
if (err == NO_ERROR) goto restart_write;
-
return err;
-
}
-
status_t Parcel::write(const void* data, size_t len)
-
{
-
void* const d = writeInplace(len);
-
if (d) {
-
memcpy(d, data, len);
-
return NO_ERROR;
-
}
-
return mError;
-
}
-
void* Parcel::writeInplace(size_t len)
-
{
-
const size_t padded = PAD_SIZE(len);
-
// sanity check for integer overflow
-
if (mDataPos+padded < mDataPos) {
-
return NULL;
-
}
-
if ((mDataPos+padded) <= mDataCapacity) {
-
restart_write:
-
//printf(“Writing %ld bytes, padded to %ld/n”, len, padded);
-
uint8_t* const data = mData+mDataPos;
-
// Need to pad at end?
-
if (padded != len) {
-
#if BYTE_ORDER == BIG_ENDIAN
-
static const uint32_t mask[4] = {
-
0x00000000, 0xffffff00, 0xffff0000, 0xff000000
-
};
-
#endif
-
#if BYTE_ORDER == LITTLE_ENDIAN
-
static const uint32_t mask[4] = {
-
0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
-
};
-
#endif
-
//printf(“Applying pad mask: %p to %p/n”, (void*)mask[padded-len],
-
// *reinterpret_cast<void**>(data+padded-4));
-
*reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];
-
}
-
finishWrite(padded);
-
return data;
-
}
-
status_t err = growData(padded);
-
if (err == NO_ERROR) goto restart_write;
-
return NULL;
-
}
-
status_t Parcel::writeInt32(int32_t val)
-
{
-
return writeAligned(val);
-
}
-
status_t Parcel::writeInt64(int64_t val)
-
{
-
return writeAligned(val);
-
}
-
status_t Parcel::writeFloat(float val)
-
{
-
return writeAligned(val);
-
}
-
status_t Parcel::writeDouble(double val)
-
{
-
return writeAligned(val);
-
}
-
status_t Parcel::writeIntPtr(intptr_t val)
-
{
-
return writeAligned(val);
-
}
-
status_t Parcel::writeCString(const char* str)
-
{
-
return write(str, strlen(str)+1);
-
}
-
status_t Parcel::writeString8(const String8& str)
-
{
-
status_t err = writeInt32(str.bytes());
-
if (err == NO_ERROR) {
-
err = write(str.string(), str.bytes()+1);
-
}
-
return err;
-
}
-
status_t Parcel::writeString16(const String16& str)
-
{
-
return writeString16(str.string(), str.size());
-
}
-
status_t Parcel::writeString16(const char16_t* str, size_t len)
-
{
-
if (str == NULL) return writeInt32(-1);
-
status_t err = writeInt32(len);
-
if (err == NO_ERROR) {
-
len *= sizeof(char16_t);
-
uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
-
if (data) {
-
memcpy(data, str, len);
-
*reinterpret_cast<char16_t*>(data+len) = 0;
-
return NO_ERROR;
-
}
-
err = mError;
-
}
-
return err;
-
}
-
status_t Parcel::writeStrongBinder(const sp& val)
-
{
-
return flatten_binder(ProcessState::self(), val, this);
-
}
-
status_t Parcel::writeWeakBinder(const wp& val)
-
{
-
return flatten_binder(ProcessState::self(), val, this);
-
}
-
status_t Parcel::writeNativeHandle(const native_handle* handle)
-
{
-
if (!handle || handle->version != sizeof(native_handle))
-
return BAD_TYPE;
-
status_t err;
-
err = writeInt32(handle->numFds);
-
if (err != NO_ERROR) return err;
-
err = writeInt32(handle->numInts);
-
if (err != NO_ERROR) return err;
-
for (int i=0 ; err==NO_ERROR && inumFds ; i++)
-
err = writeDupFileDescriptor(handle->data[i]);
-
if (err != NO_ERROR) {
-
LOGD(“write native handle, write dup fd failed”);
-
return err;
-
}
-
err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
-
return err;
-
}
-
status_t Parcel::writeFileDescriptor(int fd)
-
{
-
flat_binder_object obj;
-
obj.type = BINDER_TYPE_FD;
-
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
-
obj.handle = fd;
-
obj.cookie = (void*)0;
-
return writeObject(obj, true);
-
}
-
status_t Parcel::writeDupFileDescriptor(int fd)
-
{
-
flat_binder_object obj;
-
obj.type = BINDER_TYPE_FD;
-
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
-
obj.handle = dup(fd);
-
obj.cookie = (void*)1;
-
return writeObject(obj, true);
-
}
-
status_t Parcel::write(const Flattenable& val)
-
{
-
status_t err;
-
// size if needed
-
size_t len = val.getFlattenedSize();
-
size_t fd_count = val.getFdCount();
-
err = this->writeInt32(len);
-
if (err) return err;
-
err = this->writeInt32(fd_count);
-
if (err) return err;
-
// payload
-
void* buf = this->writeInplace(PAD_SIZE(len));
-
if (buf == NULL)
-
return BAD_VALUE;
-
int* fds = NULL;
-
if (fd_count) {
-
fds = new int[fd_count];
-
}
-
err = val.flatten(buf, len, fds, fd_count);
-
for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
-
err = this->writeDupFileDescriptor( fds[i] );
-
}
-
if (fd_count) {
-
delete [] fds;
-
}
-
return err;
-
}
-
status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
-
{
-
const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
-
const bool enoughObjects = mObjectsSize < mObjectsCapacity;
-
if (enoughData && enoughObjects) {
-
restart_write:
-
*reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
-
// Need to write meta-data?
-
if (nullMetaData || val.binder != NULL) {
-
mObjects[mObjectsSize] = mDataPos;
-
acquire_object(ProcessState::self(), val, this);
-
mObjectsSize++;
-
}
-
// remember if it’s a file descriptor
-
if (val.type == BINDER_TYPE_FD) {
-
mHasFds = mFdsKnown = true;
-
}
-
return finishWrite(sizeof(flat_binder_object));
-
}
-
if (!enoughData) {
-
const status_t err = growData(sizeof(val));
-
if (err != NO_ERROR) return err;
-
}
-
if (!enoughObjects) {
-
size_t newSize = ((mObjectsSize+2)*3)/2;
-
size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t));
-
if (objects == NULL) return NO_MEMORY;
-
mObjects = objects;
-
mObjectsCapacity = newSize;
-
}
-
goto restart_write;
-
}
-
void Parcel::remove(size_t start, size_t amt)
-
{
-
LOG_ALWAYS_FATAL(“Parcel::remove() not yet implemented!”);
-
}
-
status_t Parcel::read(void* outData, size_t len) const
-
{
-
if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
-
memcpy(outData, mData+mDataPos, len);
-
mDataPos += PAD_SIZE(len);
-
LOGV(“read Setting data pos of %p to %d/n”, this, mDataPos);
-
return NO_ERROR;
-
}
-
return NOT_ENOUGH_DATA;
-
}
-
const void* Parcel::readInplace(size_t len) const
-
{
-
if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
-
const void* data = mData+mDataPos;
-
mDataPos += PAD_SIZE(len);
-
LOGV(“readInplace Setting data pos of %p to %d/n”, this, mDataPos);
-
return data;
-
}
-
return NULL;
-
}
-
template
-
status_t Parcel::readAligned(T *pArg) const {
-
COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
-
if ((mDataPos+sizeof(T)) <= mDataSize) {
-
const void* data = mData+mDataPos;
-
mDataPos += sizeof(T);
-
*pArg = *reinterpret_cast<const T*>(data);
-
return NO_ERROR;
-
} else {
-
return NOT_ENOUGH_DATA;
-
}
-
}
-
template
-
T Parcel::readAligned() const {
-
T result;
-
if (readAligned(&result) != NO_ERROR) {
-
result = 0;
-
}
-
return result;
-
}
-
template
-
status_t Parcel::writeAligned(T val) {
-
COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
-
if ((mDataPos+sizeof(val)) <= mDataCapacity) {
-
restart_write:
-
*reinterpret_cast<T*>(mData+mDataPos) = val;
-
return finishWrite(sizeof(val));
-
}
-
status_t err = growData(sizeof(val));
-
if (err == NO_ERROR) goto restart_write;
-
return err;
-
}
-
status_t Parcel::readInt32(int32_t *pArg) const
-
{
-
return readAligned(pArg);
-
}
-
int32_t Parcel::readInt32() const
-
{
-
return readAligned<int32_t>();
-
}
-
status_t Parcel::readInt64(int64_t *pArg) const
-
{
-
return readAligned(pArg);
-
}
-
int64_t Parcel::readInt64() const
-
{
-
return readAligned<int64_t>();
-
}
-
status_t Parcel::readFloat(float *pArg) const
-
{
-
return readAligned(pArg);
-
}
-
float Parcel::readFloat() const
-
{
-
return readAligned<float>();
-
}
-
status_t Parcel::readDouble(double *pArg) const
-
{
-
return readAligned(pArg);
-
}
-
double Parcel::readDouble() const
-
{
-
return readAligned<double>();
-
}
-
status_t Parcel::readIntPtr(intptr_t *pArg) const
-
{
-
return readAligned(pArg);
-
}
-
intptr_t Parcel::readIntPtr() const
-
{
-
return readAligned<intptr_t>();
-
}
-
const char* Parcel::readCString() const
-
{
-
const size_t avail = mDataSize-mDataPos;
-
if (avail > 0) {
-
const char* str = reinterpret_cast<const char*>(mData+mDataPos);
-
// is the string’s trailing NUL within the parcel’s valid bounds?
-
const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));
-
if (eos) {
-
const size_t len = eos - str;
-
mDataPos += PAD_SIZE(len+1);
-
LOGV(“readCString Setting data pos of %p to %d/n”, this, mDataPos);
-
return str;
-
}
-
}
-
return NULL;
-
}
-
String8 Parcel::readString8() const
-
{
-
int32_t size = readInt32();
-
// watch for potential int overflow adding 1 for trailing NUL
-
if (size > 0 && size < INT32_MAX) {
-
const char* str = (const char*)readInplace(size+1);
-
if (str) return String8(str, size);
-
}
-
return String8();
-
}
-
String16 Parcel::readString16() const
-
{
-
size_t len;
-
const char16_t* str = readString16Inplace(&len);
-
if (str) return String16(str, len);
-
LOGE(“Reading a NULL string not supported here.”);
-
return String16();
-
}
-
const char16_t* Parcel::readString16Inplace(size_t* outLen) const
-
{
-
int32_t size = readInt32();
-
// watch for potential int overflow from size+1
-
if (size >= 0 && size < INT32_MAX) {
-
*outLen = size;
-
const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));
-
if (str != NULL) {
-
return str;
-
}
-
}
-
*outLen = 0;
-
return NULL;
-
}
-
sp Parcel::readStrongBinder() const
-
{
-
sp val;
-
unflatten_binder(ProcessState::self(), *this, &val);
-
return val;
-
}
-
wp Parcel::readWeakBinder() const
-
{
-
wp val;
-
unflatten_binder(ProcessState::self(), *this, &val);
-
return val;
-
}
-
native_handle* Parcel::readNativeHandle() const
-
{
-
int numFds, numInts;
-
status_t err;
-
err = readInt32(&numFds);
-
if (err != NO_ERROR) return 0;
-
err = readInt32(&numInts);
-
if (err != NO_ERROR) return 0;
-
native_handle* h = native_handle_create(numFds, numInts);
-
for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
-
h->data[i] = dup(readFileDescriptor());
-
if (h->data[i] < 0) err = BAD_VALUE;
-
}
-
err = read(h->data + numFds, sizeof(int)*numInts);
-
if (err != NO_ERROR) {
-
native_handle_close(h);
-
native_handle_delete(h);
-
h = 0;
-
}
-
return h;
-
}
-
int Parcel::readFileDescriptor() const
-
{
-
const flat_binder_object* flat = readObject(true);
-
if (flat) {
-
switch (flat->type) {
-
case BINDER_TYPE_FD:
-
//LOGI(“Returning file descriptor %ld from parcel %p/n”, flat->handle, this);
-
return flat->handle;
-
}
-
}
-
return BAD_TYPE;
-
}
-
status_t Parcel::read(Flattenable& val) const
-
{
-
// size
-
const size_t len = this->readInt32();
-
const size_t fd_count = this->readInt32();
-
// payload
-
void const* buf = this->readInplace(PAD_SIZE(len));
-
if (buf == NULL)
-
return BAD_VALUE;
-
int* fds = NULL;
-
if (fd_count) {
-
fds = new int[fd_count];
-
}
-
status_t err = NO_ERROR;
-
for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
-
fds[i] = dup(this->readFileDescriptor());
-
if (fds[i] < 0) err = BAD_VALUE;
-
}
-
if (err == NO_ERROR) {
-
err = val.unflatten(buf, len, fds, fd_count);
-
}
-
if (fd_count) {
-
delete [] fds;
-
}
-
return err;
-
}
-
const flat_binder_object* Parcel::readObject(bool nullMetaData) const
-
{
-
const size_t DPOS = mDataPos;
-
if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
-
const flat_binder_object* obj
-
= reinterpret_cast<const flat_binder_object*>(mData+DPOS);
-
mDataPos = DPOS + sizeof(flat_binder_object);
-
if (!nullMetaData && (obj->cookie == NULL && obj->binder == NULL)) {
-
// When transferring a NULL object, we don’t write it into
-
// the object list, so we don’t want to check for it when
-
// reading.
-
LOGV(“readObject Setting data pos of %p to %d/n”, this, mDataPos);
-
return obj;
-
}
-
// Ensure that this object is valid…
-
size_t* const OBJS = mObjects;
-
const size_t N = mObjectsSize;
-
size_t opos = mNextObjectHint;
-
if (N > 0) {
-
LOGV(“Parcel %p looking for obj at %d, hint=%d/n”,
-
this, DPOS, opos);
-
// Start at the current hint position, looking for an object at
-
// the current data position.
-
if (opos < N) {
-
while (opos < (N-1) && OBJS[opos] < DPOS) {
-
opos++;
-
}
-
} else {
-
opos = N-1;
-
}
-
if (OBJS[opos] == DPOS) {
-
// Found it!
-
LOGV(“Parcel found obj %d at index %d with forward search”,
-
this, DPOS, opos);
-
mNextObjectHint = opos+1;
-
LOGV(“readObject Setting data pos of %p to %d/n”, this, mDataPos);
-
return obj;
-
}
-
// Look backwards for it…
-
while (opos > 0 && OBJS[opos] > DPOS) {
-
opos–;
-
}
-
if (OBJS[opos] == DPOS) {
-
// Found it!
-
LOGV(“Parcel found obj %d at index %d with backward search”,
-
this, DPOS, opos);
-
mNextObjectHint = opos+1;
-
LOGV(“readObject Setting data pos of %p to %d/n”, this, mDataPos);
-
return obj;
-
}
-
}
-
LOGW(“Attempt to read object from Parcel %p at offset %d that is not in the object list”,
-
this, DPOS);
-
}
-
return NULL;
-
}
-
void Parcel::closeFileDescriptors()
-
{
-
size_t i = mObjectsSize;
-
if (i > 0) {
-
//LOGI(“Closing file descriptors for %d objects…”, mObjectsSize);
-
}
-
while (i > 0) {
-
i–;
-
const flat_binder_object* flat
-
= reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
-
if (flat->type == BINDER_TYPE_FD) {
-
//LOGI(“Closing fd: %ld/n”, flat->handle);
-
close(flat->handle);
-
}
-
}
-
}
-
const uint8_t* Parcel::ipcData() const
-
{
-
return mData;
-
}
-
size_t Parcel::ipcDataSize() const
-
{
-
return (mDataSize > mDataPos ? mDataSize : mDataPos);
-
}
-
const size_t* Parcel::ipcObjects() const
-
{
-
return mObjects;
-
}
-
size_t Parcel::ipcObjectsCount() const
-
{
-
return mObjectsSize;
-
}
-
void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
-
const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
-
{
-
freeDataNoInit();
-
mError = NO_ERROR;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
尾声
评论里面有些同学有疑问关于如何学习material design控件,我的建议是去GitHub搜,有很多同行给的例子,这些栗子足够入门。
有朋友说要是动真格的话,需要NDK以及JVM等的知识,首现**NDK并不是神秘的东西,**你跟着官方的步骤走一遍就知道什么回事了,无非就是一些代码格式以及原生/JAVA内存交互,进阶一点的有原生/JAVA线程交互,线程交互确实有点蛋疼,但平常避免用就好了,再说对于初学者来说关心NDK干嘛,据鄙人以前的经历,只在音视频通信和一个嵌入式信号处理(离线)的两个项目中用过,嵌入式信号处理是JAVA->NDK->.SO->MATLAB这样调用的我原来MATLAB的代码,其他的大多就用在游戏上了吧,一般的互联网公司会有人给你公司的SO包的。
至于JVM,该掌握的那部分,相信我,你会掌握的,不该你掌握的,有那些专门研究JVM的人来做,不如省省心有空看看计算机系统,编译原理。
一句话,平常多写多练,这是最基本的程序员的素质,尽量挤时间,读理论基础书籍,JVM不是未来30年唯一的虚拟机,JAVA也不一定再风靡未来30年工业界,其他的系统和语言也会雨后春笋冒出来,但你理论扎实会让你很快理解学会一个语言或者框架,你平常写的多会让你很快熟练的将新学的东西应用到实际中。
初学者,一句话,多练。
at->handle);
-
}
-
}
-
}
-
const uint8_t* Parcel::ipcData() const
-
{
-
return mData;
-
}
-
size_t Parcel::ipcDataSize() const
-
{
-
return (mDataSize > mDataPos ? mDataSize : mDataPos);
-
}
-
const size_t* Parcel::ipcObjects() const
-
{
-
return mObjects;
-
}
-
size_t Parcel::ipcObjectsCount() const
-
{
-
return mObjectsSize;
-
}
-
void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
-
const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
-
{
-
freeDataNoInit();
-
mError = NO_ERROR;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-KLUrssCT-1710507451184)]
[外链图片转存中…(img-95ypRGhr-1710507451185)]
[外链图片转存中…(img-K1NsV9CS-1710507451185)]
[外链图片转存中…(img-zDBe2wTr-1710507451186)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-jE3ne6Gt-1710507451186)]
尾声
评论里面有些同学有疑问关于如何学习material design控件,我的建议是去GitHub搜,有很多同行给的例子,这些栗子足够入门。
有朋友说要是动真格的话,需要NDK以及JVM等的知识,首现**NDK并不是神秘的东西,**你跟着官方的步骤走一遍就知道什么回事了,无非就是一些代码格式以及原生/JAVA内存交互,进阶一点的有原生/JAVA线程交互,线程交互确实有点蛋疼,但平常避免用就好了,再说对于初学者来说关心NDK干嘛,据鄙人以前的经历,只在音视频通信和一个嵌入式信号处理(离线)的两个项目中用过,嵌入式信号处理是JAVA->NDK->.SO->MATLAB这样调用的我原来MATLAB的代码,其他的大多就用在游戏上了吧,一般的互联网公司会有人给你公司的SO包的。
至于JVM,该掌握的那部分,相信我,你会掌握的,不该你掌握的,有那些专门研究JVM的人来做,不如省省心有空看看计算机系统,编译原理。
一句话,平常多写多练,这是最基本的程序员的素质,尽量挤时间,读理论基础书籍,JVM不是未来30年唯一的虚拟机,JAVA也不一定再风靡未来30年工业界,其他的系统和语言也会雨后春笋冒出来,但你理论扎实会让你很快理解学会一个语言或者框架,你平常写的多会让你很快熟练的将新学的东西应用到实际中。
初学者,一句话,多练。
由于文章篇幅问题复制链接查看详细文章以及获取学习笔记链接:前往我的GitHub