OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chromeos/binder/command_broker.h" | 5 #include "chromeos/binder/command_broker.h" |
6 | 6 |
7 #include <linux/android/binder.h> | 7 #include <linux/android/binder.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "chromeos/binder/driver.h" | 13 #include "chromeos/binder/driver.h" |
14 #include "chromeos/binder/local_object.h" | 14 #include "chromeos/binder/local_object.h" |
15 #include "chromeos/binder/transaction_data.h" | 15 #include "chromeos/binder/transaction_data.h" |
| 16 #include "chromeos/binder/transaction_status.h" |
16 | 17 |
17 namespace binder { | 18 namespace binder { |
18 | 19 |
19 namespace { | 20 namespace { |
20 | 21 |
21 // Converts TransactionData to binder_transaction_data struct. | 22 // Converts TransactionData to binder_transaction_data struct. |
22 binder_transaction_data ConvertTransactionDataToStruct( | 23 binder_transaction_data ConvertTransactionDataToStruct( |
23 const TransactionData& data) { | 24 const TransactionData& data) { |
24 binder_transaction_data result = {}; | 25 binder_transaction_data result = {}; |
25 result.code = data.GetCode(); | 26 result.code = data.GetCode(); |
(...skipping 14 matching lines...) Expand all Loading... |
40 | 41 |
41 } // namespace | 42 } // namespace |
42 | 43 |
43 CommandBroker::CommandBroker(Driver* driver) | 44 CommandBroker::CommandBroker(Driver* driver) |
44 : command_stream_(driver, this), weak_ptr_factory_(this) {} | 45 : command_stream_(driver, this), weak_ptr_factory_(this) {} |
45 | 46 |
46 CommandBroker::~CommandBroker() { | 47 CommandBroker::~CommandBroker() { |
47 DCHECK(thread_checker_.CalledOnValidThread()); | 48 DCHECK(thread_checker_.CalledOnValidThread()); |
48 } | 49 } |
49 | 50 |
| 51 bool CommandBroker::EnterLooper() { |
| 52 command_stream_.AppendOutgoingCommand(BC_ENTER_LOOPER, nullptr, 0); |
| 53 return command_stream_.Flush(); |
| 54 } |
| 55 |
| 56 bool CommandBroker::ExitLooper() { |
| 57 command_stream_.AppendOutgoingCommand(BC_EXIT_LOOPER, nullptr, 0); |
| 58 return command_stream_.Flush(); |
| 59 } |
| 60 |
| 61 bool CommandBroker::PollCommands() { |
| 62 // Fetch and process commands. |
| 63 if (!command_stream_.Fetch()) { |
| 64 LOG(ERROR) << "Failed to fetch commands."; |
| 65 return false; |
| 66 } |
| 67 while (command_stream_.CanProcessIncomingCommand()) { |
| 68 if (!command_stream_.ProcessIncomingCommand()) { |
| 69 LOG(ERROR) << "Failed to process command."; |
| 70 return false; |
| 71 } |
| 72 } |
| 73 // Flush outgoing commands. |
| 74 if (!command_stream_.Flush()) { |
| 75 LOG(ERROR) << "Failed to flush commands."; |
| 76 return false; |
| 77 } |
| 78 return true; |
| 79 } |
| 80 |
50 bool CommandBroker::Transact(int32_t handle, | 81 bool CommandBroker::Transact(int32_t handle, |
51 const TransactionData& request, | 82 const TransactionData& request, |
52 scoped_ptr<TransactionData>* reply) { | 83 scoped_ptr<TransactionData>* reply) { |
53 DCHECK(thread_checker_.CalledOnValidThread()); | 84 DCHECK(thread_checker_.CalledOnValidThread()); |
54 // Send transaction. | 85 // Send transaction. |
55 binder_transaction_data tr = ConvertTransactionDataToStruct(request); | 86 binder_transaction_data tr = ConvertTransactionDataToStruct(request); |
56 tr.target.handle = handle; | 87 tr.target.handle = handle; |
57 command_stream_.AppendOutgoingCommand(BC_TRANSACTION, &tr, sizeof(tr)); | 88 command_stream_.AppendOutgoingCommand(BC_TRANSACTION, &tr, sizeof(tr)); |
58 if (!command_stream_.Flush()) { | 89 if (!command_stream_.Flush()) { |
59 LOG(ERROR) << "Failed to write"; | 90 LOG(ERROR) << "Failed to write"; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 command_stream_.AppendOutgoingCommand(BC_RELEASE, &handle, sizeof(handle)); | 124 command_stream_.AppendOutgoingCommand(BC_RELEASE, &handle, sizeof(handle)); |
94 // Decrement weak reference count. | 125 // Decrement weak reference count. |
95 command_stream_.AppendOutgoingCommand(BC_DECREFS, &handle, sizeof(handle)); | 126 command_stream_.AppendOutgoingCommand(BC_DECREFS, &handle, sizeof(handle)); |
96 } | 127 } |
97 | 128 |
98 base::Closure CommandBroker::GetReleaseReferenceClosure(int32_t handle) { | 129 base::Closure CommandBroker::GetReleaseReferenceClosure(int32_t handle) { |
99 return base::Bind(&CommandBroker::ReleaseReference, | 130 return base::Bind(&CommandBroker::ReleaseReference, |
100 weak_ptr_factory_.GetWeakPtr(), handle); | 131 weak_ptr_factory_.GetWeakPtr(), handle); |
101 } | 132 } |
102 | 133 |
| 134 bool CommandBroker::OnTransaction(const TransactionData& data) { |
| 135 LocalObject* object = reinterpret_cast<LocalObject*>(data.GetCookie()); |
| 136 scoped_ptr<TransactionData> reply; |
| 137 if (!object->Transact(this, data, &reply)) { |
| 138 LOG(ERROR) << "Failed to transact."; |
| 139 return false; |
| 140 } |
| 141 if (!data.IsOneWay()) { |
| 142 // Send reply. |
| 143 if (!reply) { |
| 144 reply.reset(new TransactionStatus(Status::FAILED_TRANSACTION)); |
| 145 } |
| 146 binder_transaction_data tr = ConvertTransactionDataToStruct(*reply); |
| 147 tr.target.handle = -1; // This value will be ignored. Set invalid handle. |
| 148 command_stream_.AppendOutgoingCommand(BC_REPLY, &tr, sizeof(tr)); |
| 149 if (!command_stream_.Flush()) { |
| 150 LOG(ERROR) << "Failed to write"; |
| 151 return false; |
| 152 } |
| 153 scoped_ptr<TransactionData> response_data; |
| 154 ResponseType response_type = WaitForResponse(&response_data); |
| 155 // Not returning false for errors here, as doing it can result in letting |
| 156 // another process abort the loop in PollCommands() (e.g. any process can |
| 157 // cause a "dead binder" error with crash). We should return false only for |
| 158 // fundamental errors like binder protocol errors. |
| 159 LOG_IF(ERROR, response_type != RESPONSE_TYPE_TRANSACTION_COMPLETE) |
| 160 << "Error on the other end when sending reply: " << response_type; |
| 161 } |
| 162 return true; |
| 163 } |
| 164 |
103 void CommandBroker::OnReply(scoped_ptr<TransactionData> data) { | 165 void CommandBroker::OnReply(scoped_ptr<TransactionData> data) { |
104 DCHECK(thread_checker_.CalledOnValidThread()); | 166 DCHECK(thread_checker_.CalledOnValidThread()); |
105 DCHECK_EQ(response_type_, RESPONSE_TYPE_NONE); | 167 DCHECK_EQ(response_type_, RESPONSE_TYPE_NONE); |
106 DCHECK(!response_data_); | 168 DCHECK(!response_data_); |
107 response_type_ = RESPONSE_TYPE_TRANSACTION_REPLY; | 169 response_type_ = RESPONSE_TYPE_TRANSACTION_REPLY; |
108 response_data_ = std::move(data); | 170 response_data_ = std::move(data); |
109 } | 171 } |
110 | 172 |
111 void CommandBroker::OnDeadReply() { | 173 void CommandBroker::OnDeadReply() { |
112 DCHECK(thread_checker_.CalledOnValidThread()); | 174 DCHECK(thread_checker_.CalledOnValidThread()); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 } | 222 } |
161 } | 223 } |
162 } | 224 } |
163 ResponseType response_type = response_type_; | 225 ResponseType response_type = response_type_; |
164 response_type_ = RESPONSE_TYPE_NONE; | 226 response_type_ = RESPONSE_TYPE_NONE; |
165 *data = std::move(response_data_); | 227 *data = std::move(response_data_); |
166 return response_type; | 228 return response_type; |
167 } | 229 } |
168 | 230 |
169 } // namespace binder | 231 } // namespace binder |
OLD | NEW |