1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
11 #include <linux/binder.h>
21 int fd
= open("/dev/binder", O_RDONLY
);
27 if (fcntl(fd
, F_SETFD
, FD_CLOEXEC
)) {
28 AERR("fcntl FD_CLOEXEC");
31 struct binder_version version
;
32 int rv
= ioctl(fd
, BINDER_VERSION
, &version
);
34 AERR("ioctl BINDER_VERSION");
37 ALOG("Binder version: %d", version
.protocol_version
);
38 if (version
.protocol_version
!= BINDER_CURRENT_PROTOCOL_VERSION
) {
39 ALOG("Version is not compatible with current protocol: %d", BINDER_CURRENT_PROTOCOL_VERSION
);
43 void* vm
= mmap(0, BINDER_VM_SIZE
, PROT_READ
, MAP_PRIVATE
| MAP_NORESERVE
, fd
, 0);
44 if (vm
== MAP_FAILED
) {
45 AERR("mmap BINDER_VM_SIZE");
49 #define BINDER_RP(br) ALOG("return_proto: %s: %d (0x%x)", #br, br, br)
52 BINDER_RP(BR_TRANSACTION
);
54 BINDER_RP(BR_ACQUIRE_RESULT
);
55 BINDER_RP(BR_DEAD_REPLY
);
56 BINDER_RP(BR_TRANSACTION_COMPLETE
);
57 BINDER_RP(BR_INCREFS
);
58 BINDER_RP(BR_ACQUIRE
);
59 BINDER_RP(BR_RELEASE
);
60 BINDER_RP(BR_DECREFS
);
61 BINDER_RP(BR_ATTEMPT_ACQUIRE
);
63 BINDER_RP(BR_SPAWN_LOOPER
);
64 BINDER_RP(BR_FINISHED
);
65 BINDER_RP(BR_DEAD_BINDER
);
66 BINDER_RP(BR_CLEAR_DEATH_NOTIFICATION_DONE
);
67 BINDER_RP(BR_FAILED_REPLY
);
72 void CopyCommandsToBuffer(const std
::vector
<Command
*>& commands
,
73 std
::vector
<unsigned char>* buffer
) {
74 size_t last_command_size
= 0;
75 for (const Command
* command
: commands
) {
76 memcpy(&(*buffer
)[last_command_size
], reinterpret_cast<void*>(command
->GetData()), command
->GetSize());
77 last_command_size
+= command
->GetSize();
83 Channel
::Channel(uint32_t handle
)
85 driver_(ConnectDriver()),
87 reader_
.SetDataSize(256);
93 int Channel
::Call(uint32_t code
, const Parcel
& in
, Parcel
* out
) {
94 reader_
.SetDataPosition(0);
96 struct binder_write_read bwr
= {};
98 TransactionCommand
command(TransactionCommand
::TWO_WAY
);
99 command
.SetHandle(handle());
100 command
.SetCode(code
);
101 command
.SetParcel(in
);
103 bwr
.write_size
= command
.GetSize();
104 bwr
.write_buffer
= command
.GetData();
105 bwr
.read_size
= reader_
.DataSize();
106 bwr
.read_buffer
= reader_
.DataPointer();
108 int rv
= ioctl(driver_
, BINDER_WRITE_READ
, &bwr
);
109 ALOG("BINDER_WRITE_READ %d (written %d/%d, read %d/%d)", rv
, bwr
.write_consumed
, bwr
.write_size
, bwr
.read_consumed
, bwr
.read_size
);
113 for (binder_size_t index
= 0;
114 index
< bwr
.read_consumed
;
115 index
= reader_
.DataPosition()) {
116 size_t remaining
= bwr
.read_consumed
- index
;
117 if (remaining
< sizeof(uint32_t))
120 uint32_t command
= 0;
121 if (!reader_
.ReadUInt32(&command
))
124 if (!ProcessCommand(command
, remaining
))
131 bool Channel
::ProcessCommand(uint32_t command
, size_t data_remaining
) {
132 ALOG("ProcessCommand: 0x%x", command
);
135 if (data_remaining
< sizeof(int))
138 uint32_t error_code
= 0;
139 if (!reader_
.ReadUInt32(&error_code
))
142 ALOG("BR_ERROR: %d", error_code
);
152 case BR_ACQUIRE_RESULT
:
156 case BR_TRANSACTION_COMPLETE
:
166 case BR_ATTEMPT_ACQUIRE
:
171 case BR_SPAWN_LOOPER
:
177 case BR_CLEAR_DEATH_NOTIFICATION_DONE
:
179 case BR_FAILED_REPLY
:
180 ALOG("BR_FAILED_REPLY");
185 } // namespace minibind