00001
00106 bcTRANSACTION,
00107 bcREPLY,
00108
00109
00110
00111
00112 bcACQUIRE_RESULT,
00113
00114
00115
00116
00117
00118 bcFREE_BUFFER,
00119
00120
00121
00122
00123 bcINCREFS,
00124 bcACQUIRE,
00125 bcRELEASE,
00126 bcDECREFS,
00127
00128
00129
00130
00131 bcATTEMPT_ACQUIRE,
00132
00133
00134
00135
00136
00137 bcRESUME_THREAD,
00138
00139
00140
00141
00142 bcSET_THREAD_ENTRY,
00143
00144
00145
00146
00147
00148 bcREGISTER_LOOPER,
00149
00150
00151
00152
00153
00154
00155
00156 bcENTER_LOOPER,
00157 bcEXIT_LOOPER,
00158
00159
00160
00161
00162
00163
00164
00165
00166 bcCATCH_ROOT_OBJECTS,
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 bcKILL_TEAM
00177
00178
00179
00180
00181 };
00182 @endcode
00183
00184 The most interesting commands here are bcTRANSACTION and bcREPLY, which
00185 initiate an IPC transaction and return a reply for a transaction,
00186 respectively. The data structure following these commands is:
00187
00188 @code
00189 enum transaction_flags {
00190 tfInline = 0x01,
00191 tfRootObject = 0x04,
00192 tfStatusCode = 0x08
00193 };
00194
00195 struct binder_transaction_data
00196 {
00197
00198
00199 union {
00200 size_t handle;
00201 void *ptr;
00202 } target;
00203 uint32 code;
00204
00205
00206 uint32 flags;
00207 int32 priority;
00208 size_t data_size;
00209 size_t offsets_size;
00210
00211
00212
00213
00214 union {
00215 struct {
00216 const void *buffer;
00217 const void *offsets;
00218 } ptr;
00219 uint8 buf[8];
00220 } data;
00221 };
00222 @endcode
00223
00224 Thus, to initiate an IPC transaction, you will essentially perform a
00225 BINDER_READ_WRITE ioctl with the write buffer containing bcTRANSACTION
00226 follewed by a binder_transaction_data. In this structure @e target is
00227 the handle of the object that should receive the transaction (we'll talk
00228 about handles later), @e code tells the object what to do when it
00229 receives the transaction, @e priority is the thread priority to run the
00230 IPC at, and there is a @e data buffer containing the transaction data,
00231 as well as an (optional) additional @e offsets buffer of meta-data.
00232
00233 Given the @e target handle, the driver determines which process that
00234 object lives in and dispatches this transaction to one of the waiting
00235 threads in its thread pool (spawning a new thread if needed). That
00236 thread is waiting in a BINDER_WRITE_READ ioctl() to the driver, and so
00237 returns with its read buffer filled in with the commands it needs to
00238 execute. These commands a very similar to the write commands, for the
00239 most part corresponding to write operations on the other side:
00240
00241 @code
00242 enum BinderDriverReturnProtocol {
00243 brERROR = -1,
00244
00245
00246
00247
00248 brOK = 0,
00249 brTIMEOUT,
00250 brWAKEUP,
00251
00252
00253 brTRANSACTION,
00254 brREPLY,
00255
00256
00257
00258
00259 brACQUIRE_RESULT,
00260
00261
00262
00263
00264
00265 brDEAD_REPLY,
00266
00267
00268
00269
00270
00271 brTRANSACTION_COMPLETE,
00272
00273
00274
00275
00276
00277
00278 brINCREFS,
00279 brACQUIRE,
00280 brRELEASE,
00281 brDECREFS,
00282
00283
00284
00285
00286 brATTEMPT_ACQUIRE,
00287
00288
00289
00290
00291
00292 brEVENT_OCCURRED,
00293
00294
00295
00296
00297
00298
00299
00300 brFINISHED
00301 };
00302 @endcode
00303
00304 Continuing our example, the receiving thread will come back with a
00305 brTRANSACTION command at the end of its buffer. This command uses the
00306 same binder_transaction_data structure that was used to send the data,
00307 basically containing the same information that was sent but now available
00308 in the local process space.
00309
00310 The recipient, in user space will then hand this transaction over to the
00311 target object for it to execute and return its result. Upon getting the
00312 result, a new write buffer is created containing the bcREPLY reply
00313 command with a binder_transaction_data structure containing the resulting
00314 data. This is returned with a BINDER_WRITE_READ ioctl() on the driver,
00315 sending the reply back to the original process and leaving the thread
00316 waiting for the next transaction to perform.
00317
00318 The original thread finally returns back from its own BINDER_WRITE_READ
00319 with a brREPLY command containing the reply data.
00320
00321 Note that the original thread may also receive brTRANSACTION commands while
00322 it is waiting for a reply. This represents a recursion across processes —
00323 the receiving thread making a call on to an object back in the original
00324 process. It is the responsibility of the driver to keep track of all
00325 active transactions, so it can dispatch transactions to the correct thread
00326 when recursion happens.
00327
00328 @subsection ObjectMappingAndReferencing Object Mapping and Referencing
00329
00330 One of the important responsibilities of the driver is to perform mapping
00331 of objects from one process to another. This is key to both the
00332 communication mechanism (targetting and referencing objects) as well as
00333 the capability model (only allowing a particular process to perform
00334 operations on remote objects that it has been explicitly given knowledge
00335 about).
00336
00337 There are two distinct forms of an object reference: as an address in a
00338 processes's memory space, or as an abstract 32-bit handle. These
00339 representations are mutually exclusive: @b all references in a process
00340 to objects local to that process are in the form of an address, while
00341 all references to objects in another process are always in the form of
00342 a handle.
00343
00344 For example, note the @e target field of binder_transaction_data. When
00345 sending a transaction, this contains a handle to the destination object
00346 (because you always send transactions to other processes). The recipient
00347 of the transaction, however, sees this as a point to the object in its
00348 local address space. The driver maintains mappings of pointers and
00349 handles between processes so that it can perform this translation.
00350
00351 We also must be able to send references to objects through transactions.
00352 This is done by placing the object reference (either a local pointer or
00353 remote handle) in to the transaction buffer. The driver must translate
00354 this reference to the corresponding reference in the receiving process,
00355 however, just like we do with the transaction target.
00356
00357 In order to do reference translation, the driver needs to know where these
00358 references appear in the transaction data. This is where the additional
00359 @e offsets buffer comes in. It contains of a series of indicies into the
00360 data buffer, describing where objects appear. The driver can then rewrite
00361 the buffer data, translating each of those objects from the sending
00362 process reference to the correct reference in the receiving process.
00363
00364 Note that the driver does not know anything about a particular Binder
00365 object until that object is sent through the driver to another process.
00366 At that point the driver adds the object's address to its mapping table
00367 and asks the owning process to hold a reference on it. When no other
00368 processes know about the object, it is removed from the mapping table
00369 and its owning process is told to release the driver's reference. This
00370 avoids maintaining the (relatively significant) driver state for an
00371 object as long as it is only used in its local process.
00372 */