Successfully write transaction commands.
authorRobert Sesek <rsesek@chromium.org>
Thu, 22 Jan 2015 01:23:30 +0000 (20:23 -0500)
committerRobert Sesek <rsesek@chromium.org>
Thu, 22 Jan 2015 01:23:30 +0000 (20:23 -0500)
jni/minibind/channel.cc
jni/minibind/channel.h
jni/minibind/minibind.cc
jni/minibind/parcel.cc
jni/minibind/parcel.h

index 97f7b6756bfb674b0462b0698752fb13910572e3..717cbb8d42549456ea39c35093682ea851baced4 100644 (file)
@@ -46,6 +46,26 @@ int ConnectDriver() {
     abort();
   }
 
+#define BINDER_RP(br) ALOG("return_proto: %s: %d (0x%x)", #br, br, br)
+  BINDER_RP(BR_ERROR);
+  BINDER_RP(BR_OK);
+  BINDER_RP(BR_TRANSACTION);
+  BINDER_RP(BR_REPLY);
+  BINDER_RP(BR_ACQUIRE_RESULT);
+  BINDER_RP(BR_DEAD_REPLY);
+  BINDER_RP(BR_TRANSACTION_COMPLETE);
+  BINDER_RP(BR_INCREFS);
+  BINDER_RP(BR_ACQUIRE);
+  BINDER_RP(BR_RELEASE);
+  BINDER_RP(BR_DECREFS);
+  BINDER_RP(BR_ATTEMPT_ACQUIRE);
+  BINDER_RP(BR_NOOP);
+  BINDER_RP(BR_SPAWN_LOOPER);
+  BINDER_RP(BR_FINISHED);
+  BINDER_RP(BR_DEAD_BINDER);
+  BINDER_RP(BR_CLEAR_DEATH_NOTIFICATION_DONE);
+  BINDER_RP(BR_FAILED_REPLY);
+
   return fd;
 }
 
@@ -63,8 +83,6 @@ void CopyCommandsToBuffer(const std::vector<Command*>& commands,
 Channel::Channel(uint32_t handle)
     : handle_(handle),
       driver_(ConnectDriver()),
-      write_commands_size_(0),
-      write_commands_(),
       reader_() {
   reader_.SetDataSize(256);
 }
@@ -72,24 +90,23 @@ Channel::Channel(uint32_t handle)
 Channel::~Channel() {
 }
 
-void Channel::QueueCommand(Command* cmd) {
-  write_commands_size_ += cmd->GetSize();
-  write_commands_.push_back(cmd);
-}
+int Channel::Call(uint32_t code, const Parcel& in, Parcel* out) {
+  reader_.SetDataPosition(0);
 
-int Channel::TransactCommands() {
   struct binder_write_read bwr = {};
 
-  std::vector<unsigned char> write_data(write_commands_size_, 0);
-  CopyCommandsToBuffer(write_commands_, &write_data);
+  TransactionCommand command(TransactionCommand::TWO_WAY);
+  command.SetHandle(handle());
+  command.SetCode(code);
+  command.SetParcel(in);
 
-  bwr.write_size = write_commands_size_;
-  bwr.write_buffer = reinterpret_cast<binder_uintptr_t>(&write_data[0]);
+  bwr.write_size = command.GetSize();
+  bwr.write_buffer = command.GetData();
   bwr.read_size = reader_.DataSize();
   bwr.read_buffer = reader_.DataPointer();
 
   int rv = ioctl(driver_, BINDER_WRITE_READ, &bwr);
-  ALOG("BINDER_WRITE_READ %d", rv);
+  ALOG("BINDER_WRITE_READ %d (written %d/%d, read %d/%d)", rv, bwr.write_consumed, bwr.write_size, bwr.read_consumed, bwr.read_size);
   return rv;
 }
 
index bbd800401fdc57ebc4309b716522aef27dafca3a..edfa500cef310a6e7abfe3c6401289a867371c79 100644 (file)
@@ -17,26 +17,27 @@ class Command;
 
 class Channel {
  public:
+  enum {
+    FIRST_CALL_CODE = 0x00000001,
+    LAST_CALL_CODE  = 0x00ffffff,
+
+    PING_TRANSACTION = B_PACK_CHARS('_','P','N','G'),
+  };
+
   explicit Channel(uint32_t handle);
   ~Channel();
 
-  void QueueCommand(Command* cmd);
-
-  int TransactCommands();
+  int Call(uint32_t code, const Parcel& in, Parcel* out);
 
   Parcel* reader() { return &reader_; }
 
   uint32_t handle() const { return handle_; }
-  const std::vector<Command*>& write_commands() const { return write_commands_; }
 
  private:
   uint32_t handle_;
   int driver_;
 
   Parcel reader_;
-
-  size_t write_commands_size_;
-  std::vector<Command*> write_commands_;
 };
 
 }  // namespace minibind
index 0feb8e8ecb8283b2fbab0d38ed4e44eb9b24dbad..d39b3d8e26fe0e5ebcd3e88515a3dcb05913e456 100644 (file)
@@ -4,14 +4,6 @@
 
 #include "minibind.h"
 
-#include <fcntl.h>
-#include <linux/binder.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <sys/mman.h>
-
-#include <vector>
-
 #include "channel.h"
 #include "command.h"
 #include "common.h"
 
 namespace minibind {
 
-int ConnectDriver() {
-  int fd = open("/dev/binder", O_RDONLY);
-  if (fd < 0) {
-    AERR("open driver");
-    abort();
-  }
+namespace {
 
-  if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
-    AERR("fcntl FD_CLOEXEC");
-  }
+Channel* GetServiceManager() {
+  static Channel* service_manager = nullptr;
+  if (!service_manager) {
+    service_manager = new Channel(0);
 
-  struct binder_version version;
-  int rv = ioctl(fd, BINDER_VERSION, &version);
-  if (rv) {
-    AERR("ioctl BINDER_VERSION");
-    abort();
-  }
-  ALOG("Binder version: %d", version.protocol_version);
-  if (version.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION) {
-    ALOG("Version is not compatible with current protocol: %d", BINDER_CURRENT_PROTOCOL_VERSION);
-    abort();
+    Parcel in, out;
+    service_manager->Call(Channel::PING_TRANSACTION, in, &out);
+    service_manager->reader()->Print();
   }
 
-  void* vm = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, fd, 0);
-  if (vm == MAP_FAILED) {
-    AERR("mmap BINDER_VM_SIZE");
-    abort();
-  }
-
-  return fd;
+  return service_manager;
 }
 
-class Transaction {
- public:
-  Transaction() : sealed_(false),
-                  read_buffer_(),
-                  write_buffer_(),
-                  command_(),
-                  write_tx_(),
-                  read_tx_() {
-    read_buffer_.resize(64);
-  }
-  ~Transaction() {}
-
-  void WriteString8(const std::string& str) {
-    CHECK(!sealed_);
-    for (size_t i = 0; i < str.length(); ++i) {
-      write_buffer_.push_back(str[i]);
-    }
-    write_buffer_.push_back('\0');
-  }
-
-  void WriteInt32(uint32_t i) {
-    CHECK(!sealed_);
-    write_buffer_.push_back((i >> 24) & 0xFF);
-    write_buffer_.push_back((i >> 16) & 0xFF);
-    write_buffer_.push_back((i >> 8) & 0xFF);
-    write_buffer_.push_back((i >> 0) & 0xFF);
-  }
-
-  const struct binder_transaction_data* read_data() const { return &read_tx_.data; }
-
- private:
-  friend class Channel2;
-
-  struct TransactionBuffer {
-    TransactionBuffer() : command(BC_TRANSACTION), data() {}
-
-    uint32_t command;
-    struct binder_transaction_data data;
-  };
-
-  void Seal() {
-    CHECK(!sealed_);
-
-    write_tx_.data.data_size = write_buffer_.size();
-    write_tx_.data.data.ptr.buffer = reinterpret_cast<binder_uintptr_t>(&write_buffer_[0]);
-
-    read_tx_.command = BC_REPLY;
-    read_tx_.data.data_size = read_buffer_.size();
-    read_tx_.data.data.ptr.buffer = reinterpret_cast<binder_uintptr_t>(&read_buffer_[0]);
-
-    command_.write_size = sizeof(write_tx_);
-    command_.write_buffer = reinterpret_cast<binder_uintptr_t>(&write_tx_);
-    command_.read_size = sizeof(read_tx_);
-    command_.read_buffer = reinterpret_cast<binder_uintptr_t>(&read_tx_);
-
-    sealed_ = true;
-  }
-
-  bool sealed_;
-
-  std::vector<uint8_t> write_buffer_;
-  std::vector<uint8_t> read_buffer_;
-
-  struct binder_write_read command_;
-  TransactionBuffer write_tx_;
-  TransactionBuffer read_tx_;
-};
-
-class Channel2 {
- public:
-  Channel2(const std::string& interface)
-      : interface_(interface),
-        fd_(ConnectDriver()) {
-  }
-  ~Channel2() {}
-
-  Transaction* NewTransaction(uint32_t code) const {
-    Transaction* t = new Transaction();
-    t->write_tx_.data.code = code;
-    t->WriteString8(interface());
-    return t;
-  }
-
-  int ExecuteTransaction(Transaction* tx) {
-    tx->Seal();
-    int rv = ioctl(fd_, BINDER_WRITE_READ, &tx->command_);
-    ALOG("BINDER_WRITE_READ: %d", rv);
-    if (rv) {
-      AERR("BINDER_WRITE_READ");
-    }
-
-    for (size_t i = 0; i < tx->read_buffer_.size(); i += 4) {
-      ALOG("%0x %0x %0x %0x", tx->read_buffer_[i], tx->read_buffer_[i+1], tx->read_buffer_[i+2], tx->read_buffer_[i+3]);
-    }
-  }
-
-  const std::string& interface() const { return interface_; }
-
- private:
-  const std::string interface_;
-  int fd_;
-};
+}  // namespace
 
 Channel* LookupService(const std::string& name) {
   Parcel data;
   data.WriteInterfaceToken("android.os.IServiceManager");
   data.WriteUTF8(name);
 
-  Channel channel(0);
+  Parcel reply;
 
-  TransactionCommand command(TransactionCommand::TWO_WAY);
-  command.SetHandle(channel.handle());
-  command.SetCode(2 /*CHECK_SERVICE_TRANSACTION*/);
-  command.SetParcel(data);
+  Channel* channel = GetServiceManager();
+  channel->Call(2 /*CHECK_SERVICE_TRANSACTION*/, data, &reply);
 
-  channel.QueueCommand(&command);
-  channel.TransactCommands();
-  channel.reader()->Print();
+  channel->reader()->Print();
 
-#if 0
-  Channel2* ch = new Channel2("android.os.IServiceManager");
-  Transaction* tx = ch->NewTransaction(2 /*CHECK_SERVICE_TRANSACTION*/);
-  tx->WriteString8(name);
-  ch->ExecuteTransaction(tx);
-#endif
+  uint32_t cmd = 0;
+  CHECK(channel->reader()->ReadUInt32(&cmd));
+  ALOG("Got command: %x (dec %d %u)", cmd, cmd, cmd);
+  CHECK(channel->reader()->ReadUInt32(&cmd));
+  ALOG("Got command: %x (dec %d %u)", cmd, cmd, cmd);
 }
 
 }  // namespace minibind
index 7cf419d767d4f726bab80ad4c094f123a6543624..9e2367a3d60b0ab41b5c09ff67e70ad74926c86a 100644 (file)
@@ -8,7 +8,7 @@
 
 namespace minibind {
 
-Parcel::Parcel() : data_(), objects_() {}
+Parcel::Parcel() : data_position_(0), data_(), objects_() {}
 
 Parcel::~Parcel() {}
 
@@ -27,12 +27,27 @@ void Parcel::WriteUInt32(uint32_t ui32) {
   data_.push_back((ui32 >> 0) & 0xff);
 }
 
+bool Parcel::ReadUInt32(uint32_t* ui32) {
+  return ReadBytes(sizeof(*ui32), ui32);
+}
+
+bool Parcel::ReadBytes(size_t count, void* buffer) {
+  // TODO: overflow
+  ALOG("count=%d, data_position_=%d, datasize=%d", count, data_position_, DataSize());
+  if (count + data_position_ >= DataSize())
+    return false;
+
+  memcpy(buffer, &data_[data_position_], count);
+  data_position_ += count;
+  return true;
+}
+
 binder_uintptr_t Parcel::DataPointer() const {
   return reinterpret_cast<binder_uintptr_t>(&data_[0]);
 }
 
 size_t Parcel::DataSize() const {
-  return 0;
+  return data_.size();
 }
 
 void Parcel::SetDataSize(size_t size) {
@@ -41,6 +56,11 @@ void Parcel::SetDataSize(size_t size) {
   data_.resize(size);
 }
 
+void Parcel::SetDataPosition(size_t pos) {
+  CHECK(pos < DataSize());
+  data_position_ = pos;
+}
+
 void Parcel::Print() const {
   for (size_t i = 0; i < data_.size(); i += 4) {
     ALOG("%0x %0x %0x %0x", data_[i], data_[i+1], data_[i+2], data_[i+3]);
index f7718f5da22f689ffa0e7e62c41a7648b2f037e3..ba017f2037834862310ce98487fe428b23fd2456 100644 (file)
@@ -24,13 +24,19 @@ class Parcel {
   void WriteUTF8(const std::string& str);
   void WriteUInt32(uint32_t ui32);
 
+  bool ReadUInt32(uint32_t* ui32);
+  bool ReadBytes(size_t count, void* buffer);
+
   binder_uintptr_t DataPointer() const;
   size_t DataSize() const;
   void SetDataSize(size_t size);
 
+  void SetDataPosition(size_t pos);
+
   void Print() const;
 
  private:
+  size_t data_position_;
   std::vector<uint8_t> data_;
   std::vector<struct flat_binder_object> objects_;
 };