We have two processes that interact through shared memory to read / write data. One of the processes is the application (client), and the other is the background service, which is a separate application in this example, it is the ashmem service manufacturer.
AshmemService: - This is a help desk that is sticky, it provides an API for creating a shared memory channel using the android MemoryFile API. This service creates shared memory and receives a file descriptor, and fd is passed to the client process through the middleware interface.
AshmemClient: is an application that retrieves a file descriptor for a shared memory channel from AshmemService. This client application communicates with the service, after connecting it, it calls the apl apl interface to get fd. Creating a channel works fine, which creates shared memory. Now for testing purposes, I am writing a block of bytes from Client to shared memory. as soon as it is written, I try to use the same block in the service for valid data received from the application.
In the Client application, when I try to write a block of 128 bytes, the records return 0, so it looks like I can’t write to FD, which is obtained using an arbitrary binder. Even I checked that fd acts through the fd.valid () API.
pfd.getStatSize () returns -1. I think that I am not getting the correct fd from the detailed file descriptor.
http://developer.android.com/reference/android/os/Parcel.html ,
- : fd , , ..
, , , , , , , .
package com.example.service.ashmem;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
import java.nio.ByteBuffer;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.util.Log;
public class ConnectionWriter implements Parcelable {
public final static String TAG = "ConnectionWriter";
protected FileOutputStream fos = null;
protected FileDescriptor fd = null;
protected int noofBlocks = 0;
protected int blocksize = 0;
protected int lastPosition;
protected int chanId;
public ConnectionWriter(MemoryFileChannel channel, int chanId) {
this.fd = channel.getFileDescriptor();
channel.getParcelFileDescriptor();
this.chanId = chanId;
this.blocksize = channel.getBlocksize();
this.noofBlocks = channel.getNoofBlocks();
Log.d(TAG, "ctor: chanId: " + chanId + " fd valid: " + fd.valid()+ " fd: "+fd);
}
public ConnectionWriter(Parcel in) {
readFromParcel(in);
}
public static final Parcelable.Creator<ConnectionWriter> CREATOR = new
Parcelable.Creator<ConnectionWriter>() {
public ConnectionWriter createFromParcel(Parcel in) {
Log.d(TAG, "new ConnectionWriter");
return new ConnectionWriter(in);
}
@Override
public ConnectionWriter[] newArray(int arg0) {
return null;
}
};
public boolean writeBlock(ByteBuffer data, int pos)
throws IllegalArgumentException, IOException {
FileChannel fc = fos.getChannel();
Log.d(TAG, "ByteBuffer capacity : "+data.capacity());
Log.d(TAG, "location to write : "+pos*blocksize);
Log.d(TAG, "FileChannel : "+fc.isOpen() + fc.position() + fc.size());
int len = fc.write(data);
Log.d(TAG, "block write in ashmem : "+len + " fd: "+fd);
return true;
}
public void writeToParcel(Parcel out, int arg1) {
Log.d(TAG, "writeToParcel "+ "fd: "+fd + " fd valid"+ fd.valid());
out.writeInt(blocksize);
out.writeInt(noofBlocks);
out.writeFileDescriptor(fd);
out.writeInt(lastPosition);
out.writeInt(chanId);
}
public void readFromParcel(Parcel in) {
blocksize = in.readInt();
noofBlocks = in.readInt();
ParcelFileDescriptor pfd = in.readFileDescriptor();
if (pfd != null) {
fd = pfd.getFileDescriptor();
Log.d(TAG, "readFromParcel "+ "fd: "+fd);
fos = new FileOutputStream(fd);
Log.v(TAG, " fd is " + fd.valid());
long stat = pfd.getStatSize();
Log.d(TAG, " fd stat " + stat);
}
lastPosition = in.readInt();
chanId = in.readInt();
}
public int getId() {
return chanId;
}
@Override
public int describeContents() {
return 0;
}
public void close() {
try {
if (fos != null)
fos.close();
} catch (IOException ioe) {
}
}
}
adb logcat
ConnectionWriter(31694): new ConnectionWriter
ConnectionWriter(31694): readFromParcel fd: FileDescriptor[58]
ConnectionWriter(31694): fd is true
ConnectionWriter(31694): fd stat -1
ConnectionWriter(31694): ByteBuffer capacity : 128
ConnectionWriter(31694): location to write : 0
ConnectionWriter(31694): FileChannel : true00
ConnectionWriter(31694): block write in ashmem : 0 fd: FileDescriptor[58]
, , ParcelFileDescriptor. - FFD. , .