/******************************************************************/
[1]. service 实现接口并继承自Ixxx以用于通过IPC通信
[2]. 通过函数addService(String name, IBinder service)注册该服务
[3]. class DropBoxManager的成员变量为IDropBoxManagerService mService;
DropBoxManager有封装了client的调用接口
[4]. getService获得service,
[5]. 调用service提供的接口
通过DropBoxManager的实现,加深对Binder,和基于Binder的IPC的理解
/******************************************************************/
frameworks/base/core/java/android/os/DropBoxManager.java/**
* Enqueues chunks of data (from various sources -- application crashes, kernel
* log records, etc.). The queue is size bounded and will drop old data if the
* enqueued data exceeds the maximum size. You can think of this as a
* persistent, system-wide, blob-oriented "logcat".
*
* <p>You can obtain an instance of this class by calling
* {@link android.content.Context#getSystemService}
* with {@link android.content.Context#DROPBOX_SERVICE}.
*
* <p>DropBoxManager entries are not sent anywhere directly, but other system
* services and debugging tools may scan and upload entries for processing.
*/
frameworks/base/core/java/android/content/Context.java
/**
* Use with {@link #getSystemService} to retrieve a
* {@link android.os.DropBoxManager} instance for recording
* diagnostic logs.
* @see #getSystemService
*/
public static final String DROPBOX_SERVICE = "dropbox";
为什么getSystemService返回的是DropBoxManager,是因为下面的构造函数吗?
private final IDropBoxManagerService mService;
/** {@hide} */
public DropBoxManager(IDropBoxManagerService service) { mService = service; }
private final IAlarmManager mService;
AlarmManager(IAlarmManager service, Context ctx) {mService = service;}
获得接口去请求服务
/******************************************************************/
以BootReceiver为例:
/**
* Performs a number of miscellaneous, non-system-critical actions
* after the system has finished booting.
*/
public class BootReceiver extends BroadcastReceiver {
private static final String TAG = "BootReceiver";
private static final File TOMBSTONE_DIR = new File("/data/tombstones");
// Keep a reference to the observer so the finalizer doesn't disable it.
private static FileObserver sTombstoneObserver = null;
// Log boot events in the background to avoid blocking the main thread with I/O
new Thread() {
@Override
public void run() {
try {
logBootEvents(context);
} catch (Exception e) {
Slog.e(TAG, "Can't log boot events", e);
}
}
}.start();
}
private void logBootEvents(Context ctx) throws IOException {
final DropBoxManager db = (DropBoxManager) ctx.getSystemService(Context.DROPBOX_SERVICE);
final String headers = new StringBuilder(512)
.append("Build: ").append(Build.FINGERPRINT).append("\n")
.append("Hardware: ").append(Build.BOARD).append("\n")
.append("Revision: ")
.append(SystemProperties.get("ro.revision", "")).append("\n")
.append("Bootloader: ").append(Build.BOOTLOADER).append("\n")
.append("Radio: ").append(Build.RADIO).append("\n")
.append("Kernel: ")
.append(FileUtils.readTextFile(new File("/proc/version"), 1024, "...\n"))
.append("\n").toString();
if (db != null) db.addText("SYSTEM_BOOT", headers);
/******************************************************************/
3. DropBoxManager:
/**
* Stores human-readable text. The data may be discarded eventually (or even
* immediately) if space is limited, or ignored entirely if the tag has been
* blocked (see {@link #isTagEnabled}).
*
* @param tag describing the type of entry being stored
* @param data value to store
*/
public void addText(String tag, String data) {
try { mService.add(new Entry(tag, 0, data)); } catch (RemoteException e) {}
}
/** Create a new Entry with plain text contents. */
public Entry(String tag, long millis, String text) {
if (tag == null) throw new NullPointerException("tag == null");
if (text == null) throw new NullPointerException("text == null");
mTag = tag;
mTimeMillis = millis;
mData = text.getBytes();
mFileDescriptor = null;
mFlags = IS_TEXT;
}
DropBoxManager又封装了一层:has a: mService.add
/******************************************************************/
frameworks/base/core/java/com/android/internal/os/IDropBoxManagerService.aidl
make framework
/*** "Backend" interface used by {@link android.os.DropBoxManager} to talk to the
* DropBoxManagerService that actually implements the drop box functionality.
*
* @see DropBoxManager
* @hide
*/
interface IDropBoxManagerService {
/**
* @see DropBoxManager#addText
* @see DropBoxManager#addData
* @see DropBoxManager#addFile
*/
void add(in DropBoxManager.Entry entry);
/** @see DropBoxManager#getNextEntry */
boolean isTagEnabled(String tag);
/** @see DropBoxManager#getNextEntry */
DropBoxManager.Entry getNextEntry(String tag, long millis);
/*生成的对应文件*/
out/target/common/obj/JAVA_LIBRARIES/framework-full_intermediates/src/core/java/com/android/internal/os/IDropBoxManagerService.java
@Override
public void add(android.os.DropBoxManager.Entry entry) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
if ((entry!=null)) {
_data.writeInt(1);
entry.writeToParcel(_data, 0);
}
else {
_data.writeInt(0);
}
mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
Parcel是用于IPC的传输通道:client端把数据写到这里
public void writeToParcel(Parcel out, int flags) {
out.writeString(mTag);
out.writeLong(mTimeMillis);
if (mFileDescriptor != null) {
out.writeInt(mFlags & ~HAS_BYTE_ARRAY); // Clear bit just to be safe
mFileDescriptor.writeToParcel(out, flags);
} else {
out.writeInt(mFlags | HAS_BYTE_ARRAY);
out.writeByteArray(mData);
}
}
}
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case TRANSACTION_add:
{
data.enforceInterface(DESCRIPTOR);
android.os.DropBoxManager.Entry _arg0;
if ((0!=data.readInt())) {
_arg0 = android.os.DropBoxManager.Entry.CREATOR.createFromParcel(data);
}
else {
_arg0 = null;
}
this.add(_arg0);
reply.writeNoException();
return true;
}
}
/******************************************************************/
看到这里找不到this.add这里的add是怎么实现的
frameworks/base/services/core/java/com/android/server/DropBoxManagerService.java
public final class DropBoxManagerService extends IDropBoxManagerService.Stub{
}
这里的IDropBoxManagerService.Stub说的是类IDropBoxManagerService的内部类Stub
/**
* Implementation of {@link IDropBoxManagerService} using the filesystem.
* Clients use {@link DropBoxManager} to access this service.
*/
@Override
public void add(DropBoxManager.Entry entry) {
File temp = null;
OutputStream output = null;
final String tag = entry.getTag();
long time = createEntry(temp, tag, flags);
}
EntryFile:
this.file = new File(dir, Uri.encode(tag) + "@" + timestampMillis +
((flags & DropBoxManager.IS_TEXT) != 0 ? ".txt" : ".dat") +
((flags & DropBoxManager.IS_GZIPPED) != 0 ? ".gz" : ""));
/******************************************************************/
/**
* Place a new @a service called @a name into the service
* manager.
*
* @param name the name of the new service
* @param service the service object
*/
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
从类的继承关系,可知向上转型
public final class DropBoxManagerService extends IDropBoxManagerService.Stub {}