yashsingh1/xdaforums huggingface dataset:
[Android Software/Hacking General [Developers Only]] llrraa2010:
4. weak pointer

frameworks/base/include/utils/RefBase.h

template <typename T>
class wp
{
public:
typedef typename RefBase::weakref_type weakref_type;

inline wp() : m_ptr(0) { }

wp(T* other);
wp(const wp<T>& other);
wp(const sp<T>& other);
template<typename U> wp(U* other);
template<typename U> wp(const sp<U>& other);
template<typename U> wp(const wp<U>& other);

~wp();

// Assignment

wp& operator = (T* other);
wp& operator = (const wp<T>& other);
wp& operator = (const sp<T>& other);

template<typename U> wp& operator = (U* other);
template<typename U> wp& operator = (const wp<U>& other);
template<typename U> wp& operator = (const sp<U>& other);

void set_object_and_refs(T* other, weakref_type* refs);

// promotion to sp

sp<T> promote() const;

// Reset

void clear();

// Accessors

inline weakref_type* get_refs() const { return m_refs; }

inline T* unsafe_get() const { return m_ptr; }

// Operators

COMPARE_WEAK(==)
COMPARE_WEAK(!=)
COMPARE_WEAK(>)
COMPARE_WEAK(<)
COMPARE_WEAK(<=)
COMPARE_WEAK(>=)

inline bool operator == (const wp<T>& o) const {
return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
}
template<typename U>
inline bool operator == (const wp<U>& o) const {
return m_ptr == o.m_ptr;
}

inline bool operator > (const wp<T>& o) const {
return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
}
template<typename U>
inline bool operator > (const wp<U>& o) const {
return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
}

inline bool operator < (const wp<T>& o) const {
return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
}
template<typename U>
inline bool operator < (const wp<U>& o) const {
return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
}
inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }
template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
inline bool operator <= (const wp<T>& o) const { return !operator > (o); }
template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
inline bool operator >= (const wp<T>& o) const { return !operator < (o); }
template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }

private:
template<typename Y> friend class sp;
template<typename Y> friend class wp;

T* m_ptr;
weakref_type* m_refs;
};
[Android Software/Hacking General [Developers Only]] llrraa2010:
5. sample of strong pointer and weak pointer

external/weightpointer/weightpointer.cpp

#include <stdio.h>
#include <utils/RefBase.h>

#define INITIAL_STRONG_VALUE (1<<28)

using namespace android;

class WeightClass : public RefBase
{
public:
void printRefCount()
{
int32_t strong = getStrongCount();
weakref_type* ref = getWeakRefs();

printf("-----------------------\n");
printf("Strong Ref Count: %d.\n", (strong == INITIAL_STRONG_VALUE ? 0 : strong));
printf("Weak Ref Count: %d.\n", ref->getWeakCount());
printf("-----------------------\n");
}
};

class StrongClass : public WeightClass
{
public:
StrongClass()
{
printf("Construct StrongClass Object.\n");
}

virtual ~StrongClass()
{
printf("Destory StrongClass Object.\n");
}
};

class WeakClass : public WeightClass
{
public:
WeakClass()
{
extendObjectLifetime(OBJECT_LIFETIME_WEAK);

printf("Construct WeakClass Object.\n");
}

virtual ~WeakClass()
{
printf("Destory WeakClass Object.\n");
}
};

class ForeverClass : public WeightClass
{
public:
ForeverClass()
{
extendObjectLifetime(OBJECT_LIFETIME_FOREVER);

printf("Construct ForeverClass Object.\n");
}

virtual ~ForeverClass()
{
printf("Destory ForeverClass Object.\n");
}
};

void TestStrongClass(StrongClass* pStrongClass)
{
wp<StrongClass> wpOut = pStrongClass;
pStrongClass->printRefCount();

{
sp<StrongClass> spInner = pStrongClass;
pStrongClass->printRefCount();
}

sp<StrongClass> spOut = wpOut.promote();
printf("spOut: %p.\n", spOut.get());
}

void TestWeakClass(WeakClass* pWeakClass)
{
wp<WeakClass> wpOut = pWeakClass;
pWeakClass->printRefCount();

{
sp<WeakClass> spInner = pWeakClass;
pWeakClass->printRefCount();
}

pWeakClass->printRefCount();
sp<WeakClass> spOut = wpOut.promote();
printf("spOut: %p.\n", spOut.get());
}

void TestForeverClass(ForeverClass* pForeverClass)
{
wp<ForeverClass> wpOut = pForeverClass;
pForeverClass->printRefCount();

{
sp<ForeverClass> spInner = pForeverClass;
pForeverClass->printRefCount();
}
}

int main(int argc, char** argv)
{
printf("Test Strong Class: \n");
StrongClass* pStrongClass = new StrongClass();
TestStrongClass(pStrongClass);

printf("\nTest Weak Class: \n");
WeakClass* pWeakClass = new WeakClass();
TestWeakClass(pWeakClass);

printf("\nTest Froever Class: \n");
ForeverClass* pForeverClass = new ForeverClass();
TestForeverClass(pForeverClass);
pForeverClass->printRefCount();
delete pForeverClass;

return 0;
}
[Android Software/Hacking General [Developers Only]] llrraa2010:
external/weightpointer/Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := weightpointer
LOCAL_SRC_FILES := weightpointer.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils
include $(BUILD_EXECUTABLE)
[Android Software/Hacking General [Developers Only]] llrraa2010:
build and pack:

USER-NAME@MACHINE-NAME:~/Android$ mmm ./external/weightpointer
SER-NAME@MACHINE-NAME:~/Android$ make snod
[Android Software/Hacking General [Developers Only]] llrraa2010:
execution:

USER-NAME@MACHINE-NAME:~/Android$ adb shell
root@android:/ # cd system/bin/
root@android:/system/bin # ./weightpointer
[Android Software/Hacking General [Developers Only]] llrraa2010:
output of TestStrongClass:

Test Strong Class:
Construct StrongClass Object.
-----------------------
Strong Ref Count: 0.
Weak Ref Count: 1.
-----------------------
-----------------------
Strong Ref Count: 1.
Weak Ref Count: 2.
-----------------------
Destory StrongClass Object.
spOut: 0x0.
[Android Software/Hacking General [Developers Only]] llrraa2010:
Output of TestWeakClass:

Test Weak Class:
Construct WeakClass Object.
-----------------------
Strong Ref Count: 0.
Weak Ref Count: 1.
-----------------------
-----------------------
Strong Ref Count: 1.
Weak Ref Count: 2.
-----------------------
-----------------------
Strong Ref Count: 0.
Weak Ref Count: 1.
-----------------------
spOut: 0xa528.
Destory WeakClass Object.
[Android Software/Hacking General [Developers Only]] llrraa2010:
Output of TestForeverClass

Test Froever Class:
Construct ForeverClass Object.
-----------------------
Strong Ref Count: 0.
Weak Ref Count: 1.
-----------------------
-----------------------
Strong Ref Count: 1.
Weak Ref Count: 2.
[Android Software/Hacking General [Developers Only]] llrraa2010:
Output after TestForeverClass

-----------------------
Strong Ref Count: 0.
Weak Ref Count: 0.
-----------------------
Destory ForeverClass Object.
[Android Software/Hacking General [Developers Only]] llrraa2010:
chapter 21 App Widgets

http://developer.android.com/guide/practices/ui_guidelines/widget_design.html#design

http://developer.android.com/guide/topics/appwidgets/index.html

http://developer.android.com/guide/topics/appwidgets/host.html
[Android Software/Hacking General [Developers Only]] llrraa2010:
AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ango.angowidget"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="15" />

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name="AppWidget" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<intent-filter>
<action android:name="AUTO_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/appwidget_info" />
</receiver>
</application>

</manifest>
[Android Software/Hacking General [Developers Only]] llrraa2010:
appwidget_info.xml

<?xml version="1.0" encoding="UTF-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="250dp"
android:minHeight="110dp"
android:updatePeriodMillis="86400000"
android:initialLayout="@layout/digitalclock"/>
[Android Software/Hacking General [Developers Only]] llrraa2010:
digitalclock.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- res/layout/bday_widget.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="250dp"
android:layout_height="110dp"
>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="60dp"
>
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:text="0"
android:gravity="center"
android:textSize="30sp"
android:textStyle="bold"
android:layout_weight="50"
android:textColor="#ff000000"
android:background="#FFFFFF"
/>
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textSize="20sp"
android:text="Buy"
android:layout_weight="50"
android:background="#30C326"
android:textColor="#ff000000"
android:gravity="center"
/>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:background="#FF6633"
android:layout_height="match_parent" >

<ImageView
android:id="@+id/profiles"
android:layout_width="40dp"
android:layout_height="match_parent"
android:src="@drawable/ic_settings_profiles" />

</LinearLayout>

</LinearLayout>
[Android Software/Hacking General [Developers Only]] llrraa2010:
chapter 22 Learning Android build system by flashing CM ROM into oppo find5

android system structure
[Android Software/Hacking General [Developers Only]] llrraa2010:
environment and handset:

1. Ubuntu 13.04
2. CM-10.1
3. OPPO Find 5
[Android Software/Hacking General [Developers Only]] llrraa2010:
I install the CM official ROM

download the files:

http://download2.clockworkmod.com/recoveries/recovery-clockwork-6.0.4.6-find5.img
http://download.cyanogenmod.org/get/jenkins/42498/cm-10.1.3-find5.zip
[Android Software/Hacking General [Developers Only]] llrraa2010:
1. connect OPPO Find 5 with Ubuntu 13.04 installed computer through USB

2. get into the directory with recovery-clockwork-6.0.4.6-find5.img

$ cd $CM
[Android Software/Hacking General [Developers Only]] llrraa2010:
3. reboot OPPO Find 5 into Fastboot mode

$ adb reboot bootloader
[Android Software/Hacking General [Developers Only]] llrraa2010:
4. make sure fastboot is connected to OPPO Find 5

$ fastboot devices
[Android Software/Hacking General [Developers Only]] llrraa2010:
5. flash recovery

$ fastboot flash recovery recovery-clockwork-6.0.4.6-find5.img
[Android Software/Hacking General [Developers Only]] llrraa2010:
6. reboot the device

$ fastboot reboot
[Android Software/Hacking General [Developers Only]] llrraa2010:
how to get Service proxy

BpMediaPlayerService class map

frameworks/base/media/libmedia//IMediaDeathNotifier.cpp

// establish binder interface to MediaPlayerService

/*static*/const sp<IMediaPlayerService>&

IMediaDeathNotifier::getMediaPlayerService()

{

LOGV("getMediaPlayerService");

Mutex::Autolock _l(sServiceLock);

if (sMediaPlayerService.get() == 0) {

sp<IServiceManager> sm = defaultServiceManager();

sp<IBinder> binder;

do {

binder = sm->getService(String16("media.player"));

if (binder != 0) {

break;

}

LOGW("Media player service not published, waiting...");

usleep(500000); // 0.5 s

} while(true);

if (sDeathNotifier == NULL) {

sDeathNotifier = new DeathNotifier();

}

binder->linkToDeath(sDeathNotifier);

sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);

}

LOGE_IF(sMediaPlayerService == 0, "no media player service!?");

return sMediaPlayerService;

}

...
[Android Software/Hacking General [Developers Only]] llrraa2010:
Java interface for Binder IPC Driver

1　getting the Java proxy of Service Manager

class ServiceManagerProxy

class ServiceManager

frameworks/base/core/java/android/os/ServiceManager.java

public final class ServiceManager {

......

private static IServiceManager sServiceManager;

......

private static IServiceManager getIServiceManager() {

if (sServiceManager != null) {

return sServiceManager;

}

// Find the service manager

sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());

return sServiceManager;

}

......

}

2　define the Java service

frameworks/base/core/java/android/os/IHelloService.aidl

package android.os;

interface IHelloService

{

void setVal(int val);

int getVal();

}

3　start of Java service

frameworks/base/services/java/com/android/server/HelloService.java

package com.android.server;

import android.content.Context;

import android.os.IHelloService;

import android.util.Slog;

public class HelloService extends IHelloService.Stub {

private static final String TAG = "HelloService";

HelloService() {

init_native();

}

public void setVal(int val) {

setVal_native(val);

}

public int getVal() {

return getVal_native();

}

private static native boolean init_native();

private static native void setVal_native(int val);

private static native int getVal_native();

}

4　getting Java service proxy

public class Hello extends Activity implements OnClickListener {

......

private IHelloService helloService = null;

......

[MENTION=439709]override[/MENTION]

public void onCreate(Bundle savedInstanceState) {

helloService = IHelloService.Stub.asInterface(

ServiceManager.getService("hello"));

}

......

}

5　calling Java service

public class Hello extends Activity implements OnClickListener {

......

[MENTION=439709]override[/MENTION]

public void onClick(View v) {

if(v.equals(readButton)) {

int val = helloService.getVal();

......

}

else if(v.equals(writeButton)) {

......

}

else if(v.equals(clearButton)) {

......

}

}

......

}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Ashmem driver--data structure

kernel/common/mm/ashmem.c

static struct file_operations ashmem_fops = {

.owner = THIS_MODULE,

.open = ashmem_open,

.release = ashmem_release,

.mmap = ashmem_mmap,

.unlocked_ioctl = ashmem_ioctl,

.compat_ioctl = ashmem_ioctl,

};

static struct miscdevice ashmem_misc = {

.minor = MISC_DYNAMIC_MINOR,

.name = "ashmem",

.fops = &ashmem_fops,

};
[Android Software/Hacking General [Developers Only]] llrraa2010:
Ashmem driver--initialization

kernel/common/mm/ashmem.c

static int __init ashmem_init(void)

{

int ret;

......

ret = misc_register(&ashmem_misc);

if (unlikely(ret)) {

printk(KERN_ERR "ashmem: failed to register misc device!\n");

return ret;

}

......

return 0;

}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Ashmem driver--open

frameworks/base/core/java/android/os/MemoryFile.java

public class MemoryFile

{

......

private static native FileDescriptor native_open(String name, int length) throws IOException;

......

private FileDescriptor mFD; // ashmem file descriptor

......

private int mLength; // total length of our ashmem region

......

/**

* Allocates a new ashmem region. The region is initially not purgable.

*

* [MENTION=955119]param[/MENTION] name optional name for the file (can be null).

* [MENTION=955119]param[/MENTION] length of the memory file in bytes.

* [MENTION=948141]Throw[/MENTION]s IOException if the memory file could not be created.

*/

public MemoryFile(String name, int length) throws IOException {

mLength = length;

mFD = native_open(name, length);

......

}

......

}

frameworks/base/core/jni/adroid_os_MemoryFile.cpp

static jobject android_os_MemoryFile_open(JNIEnv* env, jobject clazz, jstring name, jint length)

{

const char* namestr = (name ? env->GetStringUTFChars(name, NULL) : NULL);

int result = ashmem_create_region(namestr, length);

if (name)

env->ReleaseStringUTFChars(name, namestr);

if (result < 0) {

jniThrowException(env, "java/io/IOException", "ashmem_create_region failed");

return NULL;

}

return jniCreateFileDescriptor(env, result);

}

system/core/libcutils/ashmem-dev.c

/*

* ashmem_create_region - creates a new ashmem region and returns the file

* descriptor, or <0 on error

*

* `name' is an optional label to give the region (visible in /proc/pid/maps)

* `size' is the size of the region, in page-aligned bytes

*/

int ashmem_create_region(const char *name, size_t size)

{

int fd, ret;

fd = open(ASHMEM_DEVICE, O_RDWR);

if (fd < 0)

return fd;

if (name) {

char buf[ASHMEM_NAME_LEN];

strlcpy(buf, name, sizeof(buf));

ret = ioctl(fd, ASHMEM_SET_NAME, buf);

if (ret < 0)

goto error;

}

ret = ioctl(fd, ASHMEM_SET_SIZE, size);

if (ret < 0)

goto error;

return fd;

error:

close(fd);

return ret;

}
[Android Software/Hacking General [Developers Only]] llrraa2010:
Ashmem driver--mapping to the memory

public class MemoryFile

{

......

// returns memory address for ashmem region

private static native int native_mmap(FileDescriptor fd, int length, int mode)

throws IOException;

......

private int mAddress; // address of ashmem memory

......

/**

* Allocates a new ashmem region. The region is initially not purgable.

*

* [MENTION=955119]param[/MENTION] name optional name for the file (can be null).

* [MENTION=955119]param[/MENTION] length of the memory file in bytes.

* [MENTION=948141]Throw[/MENTION]s IOException if the memory file could not be created.

*/

public MemoryFile(String name, int length) throws IOException {

......

mAddress = native_mmap(mFD, length, PROT_READ | PROT_WRITE);

......

}

}

frameworks/base/core/jni/adroid_os_MemoryFile.cpp

static jint android_os_MemoryFile_mmap(JNIEnv* env, jobject clazz, jobject fileDescriptor,

jint length, jint prot)

{

int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

jint result = (jint)mmap(NULL, length, prot, MAP_SHARED, fd, 0);

if (!result)

jniThrowException(env, "java/io/IOException", "mmap failed");

return result;

}

static int ashmem_mmap(struct file *file, struct vm_area_struct *vma)

{

struct ashmem_area *asma = file->private_data;

int ret = 0;

mutex_lock(&ashmem_mutex);

/* user needs to SET_SIZE before mapping */

if (unlikely(!asma->size)) {

ret = -EINVAL;

goto out;

}

/* requested protection bits must match our allowed protection mask */

if (unlikely((vma->vm_flags & ~asma->prot_mask) & PROT_MASK)) {

ret = -EPERM;

goto out;

}

if (!asma->file) {

char *name = ASHMEM_NAME_DEF;

struct file *vmfile;

if (asma->name[ASHMEM_NAME_PREFIX_LEN] != '\0')

name = asma->name;

/* ... and allocate the backing shmem file */

vmfile = shmem_file_setup(name, asma->size, vma->vm_flags);

if (unlikely(IS_ERR(vmfile))) {

ret = PTR_ERR(vmfile);

goto out;

}

asma->file = vmfile;

}

get_file(asma->file);

if (vma->vm_flags & VM_SHARED)

shmem_set_file(vma, asma->file);

else {

if (vma->vm_file)

fput(vma->vm_file);

vma->vm_file = asma->file;

}

vma->vm_flags |= VM_CAN_NONLINEAR;

out:

mutex_unlock(&ashmem_mutex);

return ret;

}
[Android Software/Hacking General [Developers Only]] Jolest:
Source code and class diagrams isn't an explanation of anything... It's interesting to a geek, but doesn't help someone understand what's happening. If this is what you're planning to publish, you might want to rethink what it is you're trying to accomplish.
[Android Software/Hacking General [Developers Only]] llrraa2010:
First of all, thanks for the comment.

Source code and class diagrams isn't an explanation of anything, but this is just the pilot content. If someone has question on that, he could share it here, then more details would be shared, and the final content of the book would be adjust based on the discussion here.
[Android Software/Hacking General [Developers Only]] llrraa2010:
Ashmem driver--pin and unpin

system/core/libcutils/ashmem-dev.c

int ashmem_pin_region(int fd, size_t offset, size_t len)

{

struct ashmem_pin pin = { offset, len };

return ioctl(fd, ASHMEM_PIN, &pin);

}

int ashmem_unpin_region(int fd, size_t offset, size_t len)

{

struct ashmem_pin pin = { offset, len };

return ioctl(fd, ASHMEM_UNPIN, &pin);

}

kernel/common/include/linux/ashmem.h

#define __ASHMEMIOC	0x77

#define ASHMEM_PIN	_IOW(__ASHMEMIOC, 7, struct ashmem_pin)

#define ASHMEM_UNPIN	_IOW(__ASHMEMIOC, 8, struct ashmem_pin)

kernel/common/include/linux/ashmem.h

struct ashmem_pin {

__u32 offset;	/* offset into region, in bytes, page-aligned */

__u32 len;	/* length forward from offset, in bytes, page-aligned */

};
[Android Software/Hacking General [Developers Only]] llrraa2010:
Ashmem driver--how Ashmem shares memory

kernel/common/drivers/staging/android/binder.h

/*

* This is the flattened representation of a Binder object for transfer

* between processes. The 'offsets' supplied as part of a binder transaction

* contains offsets into the data where these structures occur. The Binder

* driver takes care of re-writing the structure type and data as it moves

* between processes.

*/

struct flat_binder_object {

/* 8 bytes for large_flat_header. */

unsigned long type;

unsigned long flags;

/* 8 bytes of data. */

union {

void *binder; /* local object */

signed long handle; /* remote object */

};

/* extra data associated with local object */

void *cookie;

};

enum {

BINDER_TYPE_BINDER = B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE),

BINDER_TYPE_WEAK_BINDER = B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE),

BINDER_TYPE_HANDLE = B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE),

BINDER_TYPE_WEAK_HANDLE = B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE),

BINDER_TYPE_FD = B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE),

};

kernel/common/drivers/staging/android/binder.c

static void

binder_transaction(struct binder_proc *proc, struct binder_thread *thread,

struct binder_transaction_data *tr, int reply)

{

struct binder_transaction *t;

struct binder_work *tcomplete;

size_t *offp, *off_end;

struct binder_proc *target_proc;

struct binder_thread *target_thread = NULL;

struct binder_node *target_node = NULL;

struct list_head *target_list;

wait_queue_head_t *target_wait;

struct binder_transaction *in_reply_to = NULL;

struct binder_transaction_log_entry *e;

uint32_t return_error;

......

offp = (size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *)));

......

off_end = (void *)offp + tr->offsets_size;

for (; offp < off_end; offp++) {

struct flat_binder_object *fp;

......

fp = (struct flat_binder_object *)(t->buffer->data + *offp);

switch (fp->type) {

......

case BINDER_TYPE_FD: {

int target_fd;

struct file *file;

if (reply) {

if (!(in_reply_to->flags & TF_ACCEPT_FDS)) {

binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n",

proc->pid, thread->pid, fp->handle);

return_error = BR_FAILED_REPLY;

goto err_fd_not_allowed;

}

} else if (!target_node->accept_fds) {

binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n",

proc->pid, thread->pid, fp->handle);

return_error = BR_FAILED_REPLY;

goto err_fd_not_allowed;

}

file = fget(fp->handle);

if (file == NULL) {

binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n",

proc->pid, thread->pid, fp->handle);

return_error = BR_FAILED_REPLY;

goto err_fget_failed;

}

target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);

if (target_fd < 0) {

fput(file);

return_error = BR_FAILED_REPLY;

goto err_get_unused_fd_failed;

}

task_fd_install(target_proc, target_fd, file);

if (binder_debug_mask & BINDER_DEBUG_TRANSACTION)

printk(KERN_INFO " fd %ld -> %d\n", fp->handle, target_fd);

/* TODO: fput? */

fp->handle = target_fd;

} break;

......

}

}

......

}