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.
8 #include <linux/binder.h>
23 int fd
= open("/dev/binder", O_RDONLY
);
29 if (fcntl(fd
, F_SETFD
, FD_CLOEXEC
)) {
30 AERR("fcntl FD_CLOEXEC");
33 struct binder_version version
;
34 int rv
= ioctl(fd
, BINDER_VERSION
, &version
);
36 AERR("ioctl BINDER_VERSION");
39 ALOG("Binder version: %d", version
.protocol_version
);
40 if (version
.protocol_version
!= BINDER_CURRENT_PROTOCOL_VERSION
) {
41 ALOG("Version is not compatible with current protocol: %d", BINDER_CURRENT_PROTOCOL_VERSION
);
45 void* vm
= mmap(0, BINDER_VM_SIZE
, PROT_READ
, MAP_PRIVATE
| MAP_NORESERVE
, fd
, 0);
46 if (vm
== MAP_FAILED
) {
47 AERR("mmap BINDER_VM_SIZE");
56 Transaction() : sealed_(false),
62 read_buffer_
.resize(64);
66 void WriteString8(const std
::string
& str
) {
68 for (size_t i
= 0; i
< str
.length(); ++i
) {
69 write_buffer_
.push_back(str
[i
]);
71 write_buffer_
.push_back('\0');
74 void WriteInt32(uint32_t i
) {
76 write_buffer_
.push_back((i
>> 24) & 0xFF);
77 write_buffer_
.push_back((i
>> 16) & 0xFF);
78 write_buffer_
.push_back((i
>> 8) & 0xFF);
79 write_buffer_
.push_back((i
>> 0) & 0xFF);
82 const struct binder_transaction_data
* read_data() const { return &read_tx_
.data
; }
85 friend class Channel2
;
87 struct TransactionBuffer
{
88 TransactionBuffer() : command(BC_TRANSACTION
), data() {}
91 struct binder_transaction_data data
;
97 write_tx_
.data
.data_size
= write_buffer_
.size();
98 write_tx_
.data
.data
.ptr
.buffer
= reinterpret_cast<binder_uintptr_t
>(&write_buffer_
[0]);
100 read_tx_
.command
= BC_REPLY
;
101 read_tx_
.data
.data_size
= read_buffer_
.size();
102 read_tx_
.data
.data
.ptr
.buffer
= reinterpret_cast<binder_uintptr_t
>(&read_buffer_
[0]);
104 command_
.write_size
= sizeof(write_tx_
);
105 command_
.write_buffer
= reinterpret_cast<binder_uintptr_t
>(&write_tx_
);
106 command_
.read_size
= sizeof(read_tx_
);
107 command_
.read_buffer
= reinterpret_cast<binder_uintptr_t
>(&read_tx_
);
114 std
::vector
<uint8_t> write_buffer_
;
115 std
::vector
<uint8_t> read_buffer_
;
117 struct binder_write_read command_
;
118 TransactionBuffer write_tx_
;
119 TransactionBuffer read_tx_
;
124 Channel2(const std
::string
& interface
)
125 : interface_(interface
),
126 fd_(ConnectDriver()) {
130 Transaction
* NewTransaction(uint32_t code
) const {
131 Transaction
* t
= new Transaction();
132 t
->write_tx_
.data
.code
= code
;
133 t
->WriteString8(interface());
137 int ExecuteTransaction(Transaction
* tx
) {
139 int rv
= ioctl(fd_
, BINDER_WRITE_READ
, &tx
->command_
);
140 ALOG("BINDER_WRITE_READ: %d", rv
);
142 AERR("BINDER_WRITE_READ");
145 for (size_t i
= 0; i
< tx
->read_buffer_
.size(); i
+= 4) {
146 ALOG("%0x %0x %0x %0x", tx
->read_buffer_
[i
], tx
->read_buffer_
[i
+1], tx
->read_buffer_
[i
+2], tx
->read_buffer_
[i
+3]);
150 const std
::string
& interface() const { return interface_
; }
153 const std
::string interface_
;
157 Channel
* LookupService(const std
::string
& name
) {
159 data
.WriteInterfaceToken("android.os.IServiceManager");
160 data
.WriteUTF8(name
);
164 TransactionCommand
command(TransactionCommand
::TWO_WAY
);
165 command
.SetHandle(channel
.handle());
166 command
.SetCode(2 /*CHECK_SERVICE_TRANSACTION*/);
167 command
.SetParcel(data
);
169 channel
.QueueCommand(&command
);
170 channel
.TransactCommands();
171 channel
.reader()->Print();
174 Channel2
* ch
= new Channel2("android.os.IServiceManager");
175 Transaction
* tx
= ch
->NewTransaction(2 /*CHECK_SERVICE_TRANSACTION*/);
176 tx
->WriteString8(name
);
177 ch
->ExecuteTransaction(tx
);
181 } // namespace minibind