Skip to content

Commit

Permalink
Add WritableTransactionData
Browse files Browse the repository at this point in the history
WritableTransactionData can be used to construct TransationData to
perform transaction with a remote object.

BUG=563282

Review URL: https://codereview.chromium.org/1528263002

Cr-Commit-Position: refs/heads/master@{#365768}
  • Loading branch information
hashimoto authored and Commit bot committed Dec 17, 2015
1 parent 36aeddc commit 7ea76c7
Show file tree
Hide file tree
Showing 4 changed files with 282 additions and 0 deletions.
95 changes: 95 additions & 0 deletions chromeos/binder/writable_transaction_data.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/binder/writable_transaction_data.h"

namespace binder {

WritableTransactionData::WritableTransactionData() {}

WritableTransactionData::~WritableTransactionData() {}

uintptr_t WritableTransactionData::GetCookie() const {
return 0;
}

uint32 WritableTransactionData::GetCode() const {
return code_;
}

pid_t WritableTransactionData::GetSenderPID() const {
return 0;
}

uid_t WritableTransactionData::GetSenderEUID() const {
return 0;
}

bool WritableTransactionData::IsOneWay() const {
return is_one_way_;
}

bool WritableTransactionData::HasStatus() const {
return false;
}

Status WritableTransactionData::GetStatus() const {
return Status::OK;
}

const void* WritableTransactionData::GetData() const {
return data_.data();
}

size_t WritableTransactionData::GetDataSize() const {
return data_.size();
}

const uintptr_t* WritableTransactionData::GetObjectOffsets() const {
return object_offsets_.data();
}

size_t WritableTransactionData::GetNumObjectOffsets() const {
return object_offsets_.size();
}

void WritableTransactionData::Reserve(size_t n) {
data_.reserve(n);
}

void WritableTransactionData::WriteData(const void* data, size_t n) {
data_.insert(data_.end(), static_cast<const char*>(data),
static_cast<const char*>(data) + n);
if (n % 4 != 0) { // Add padding.
data_.resize(data_.size() + 4 - (n % 4));
}
}

void WritableTransactionData::WriteInt32(int32 value) {
// Binder is not used for inter-device communication, so no endian conversion.
// The same applies to other Write() methods.
WriteData(&value, sizeof(value));
}

void WritableTransactionData::WriteUint32(uint32 value) {
WriteData(&value, sizeof(value));
}

void WritableTransactionData::WriteInt64(int64 value) {
WriteData(&value, sizeof(value));
}

void WritableTransactionData::WriteUint64(uint64 value) {
WriteData(&value, sizeof(value));
}

void WritableTransactionData::WriteFloat(float value) {
WriteData(&value, sizeof(value));
}

void WritableTransactionData::WriteDouble(double value) {
WriteData(&value, sizeof(value));
}

} // namespace binder
79 changes: 79 additions & 0 deletions chromeos/binder/writable_transaction_data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BINDER_WRITABLE_TRANSACTION_DATA_H_
#define BINDER_WRITABLE_TRANSACTION_DATA_H_

#include <vector>

#include "base/basictypes.h"
#include "base/macros.h"
#include "chromeos/binder/transaction_data.h"

namespace binder {

// Use this class to construct TransactionData (as parameters and replies) to
// transact with remote objects.
// GetSenderPID() and GetSenderEUID() return 0.
class WritableTransactionData : public TransactionData {
public:
WritableTransactionData();
~WritableTransactionData() override;

// TransactionData override:
uintptr_t GetCookie() const override;
uint32 GetCode() const override;
pid_t GetSenderPID() const override;
uid_t GetSenderEUID() const override;
bool IsOneWay() const override;
bool HasStatus() const override;
Status GetStatus() const override;
const void* GetData() const override;
size_t GetDataSize() const override;
const uintptr_t* GetObjectOffsets() const override;
size_t GetNumObjectOffsets() const override;

// Expands the capacity of the internal buffer.
void Reserve(size_t n);

// Sets the transaction code returned by GetCode().
void SetCode(uint32 code) { code_ = code; }

// Sets the value returned by IsOneWay().
void SetIsOneWay(bool is_one_way) { is_one_way_ = is_one_way; }

// Appends the specified data with appropriate padding.
void WriteData(const void* data, size_t n);

// Appends an int32 value.
void WriteInt32(int32 value);

// Appends a uint32 value.
void WriteUint32(uint32 value);

// Appends an int64 vlaue.
void WriteInt64(int64 value);

// Appends a uint64 value.
void WriteUint64(uint64 value);

// Appends a float value.
void WriteFloat(float value);

// Appends a double value.
void WriteDouble(double value);
// TODO(hashimoto): Support more types (i.e. strings, FDs, objects).

private:
uint32 code_ = 0;
bool is_one_way_ = false;
std::vector<char> data_;
std::vector<uintptr_t> object_offsets_;

DISALLOW_COPY_AND_ASSIGN(WritableTransactionData);
};

} // namespace binder

#endif // BINDER_WRITABLE_TRANSACTION_DATA_H_
105 changes: 105 additions & 0 deletions chromeos/binder/writable_transaction_data_unittest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/binder/buffer_reader.h"
#include "chromeos/binder/writable_transaction_data.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace binder {

TEST(BinderWritableTransactionDataTest, WriteData) {
char array[3];
for (size_t i = 0; i < sizeof(array); ++i) {
array[i] = i;
}

WritableTransactionData data;
EXPECT_EQ(0u, data.GetDataSize());
data.WriteData(array, sizeof(array));
EXPECT_EQ(4u, data.GetDataSize()); // Padded for 4-byte alignment.
for (size_t i = 0; i < sizeof(array); ++i) {
SCOPED_TRACE(i);
EXPECT_EQ(array[i], reinterpret_cast<const char*>(data.GetData())[i]);
}
}

TEST(BinderWritableTransactionDataTest, WriteInt32) {
const int32 kValue = -1234;
WritableTransactionData data;
data.WriteInt32(kValue);
EXPECT_EQ(sizeof(kValue), data.GetDataSize());
BufferReader reader(reinterpret_cast<const char*>(data.GetData()),
data.GetDataSize());
int32 result = 0;
EXPECT_TRUE(reader.Read(&result, sizeof(result)));
EXPECT_EQ(kValue, result);
EXPECT_FALSE(reader.HasMoreData());
}

TEST(BinderWritableTransactionDataTest, WriteUint32) {
const uint32 kValue = 1234;
WritableTransactionData data;
data.WriteUint32(kValue);
EXPECT_EQ(sizeof(kValue), data.GetDataSize());
BufferReader reader(reinterpret_cast<const char*>(data.GetData()),
data.GetDataSize());
uint32 result = 0;
EXPECT_TRUE(reader.Read(&result, sizeof(result)));
EXPECT_EQ(kValue, result);
EXPECT_FALSE(reader.HasMoreData());
}

TEST(BinderWritableTransactionDataTest, WriteInt64) {
const int64 kValue = -1234;
WritableTransactionData data;
data.WriteInt64(kValue);
EXPECT_EQ(sizeof(kValue), data.GetDataSize());
BufferReader reader(reinterpret_cast<const char*>(data.GetData()),
data.GetDataSize());
int64 result = 0;
EXPECT_TRUE(reader.Read(&result, sizeof(result)));
EXPECT_EQ(kValue, result);
EXPECT_FALSE(reader.HasMoreData());
}

TEST(BinderWritableTransactionDataTest, WriteUint64) {
const uint64 kValue = 1234;
WritableTransactionData data;
data.WriteUint64(kValue);
EXPECT_EQ(sizeof(kValue), data.GetDataSize());
BufferReader reader(reinterpret_cast<const char*>(data.GetData()),
data.GetDataSize());
uint64 result = 0;
EXPECT_TRUE(reader.Read(&result, sizeof(result)));
EXPECT_EQ(kValue, result);
EXPECT_FALSE(reader.HasMoreData());
}

TEST(BinderWritableTransactionDataTest, WriteFloat) {
const float kValue = 1234.5678;
WritableTransactionData data;
data.WriteFloat(kValue);
EXPECT_EQ(sizeof(kValue), data.GetDataSize());
BufferReader reader(reinterpret_cast<const char*>(data.GetData()),
data.GetDataSize());
float result = 0;
EXPECT_TRUE(reader.Read(&result, sizeof(result)));
EXPECT_EQ(kValue, result);
EXPECT_FALSE(reader.HasMoreData());
}

TEST(BinderWritableTransactionDataTest, WriteDouble) {
const double kValue = 1234.5678;
WritableTransactionData data;
data.WriteDouble(kValue);
EXPECT_EQ(sizeof(kValue), data.GetDataSize());
BufferReader reader(reinterpret_cast<const char*>(data.GetData()),
data.GetDataSize());
double result = 0;
EXPECT_TRUE(reader.Read(&result, sizeof(result)));
EXPECT_EQ(kValue, result);
EXPECT_FALSE(reader.HasMoreData());
}

} // namespace binder
3 changes: 3 additions & 0 deletions chromeos/chromeos.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -400,11 +400,14 @@
'binder/transaction_data_from_driver.h',
'binder/util.cc',
'binder/util.h',
'binder/writable_transaction_data.cc',
'binder/writable_transaction_data.h',
],
'chromeos_binder_test_sources': [
'binder/buffer_reader_unittest.cc',
'binder/command_stream_unittest.cc',
'binder/driver_unittest.cc',
'binder/writable_transaction_data_unittest.cc',
],
'chromeos_test_sources': [
'app_mode/kiosk_oem_manifest_parser_unittest.cc',
Expand Down

0 comments on commit 7ea76c7

Please sign in to comment.