blob: 1f2cb282b9809b162736ca850ed84d7b498de8fc [file] [log] [blame]
hashimotobb42dee2016-01-14 10:13:561// 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.
4
5#include "chromeos/binder/test_service.h"
6
7#include "base/bind.h"
hashimoto93582b22016-01-18 05:52:108#include "base/files/file_util.h"
9#include "base/files/scoped_temp_dir.h"
hashimotobb42dee2016-01-14 10:13:5610#include "base/guid.h"
dcheng0a6e80c2016-04-08 18:37:3811#include "base/memory/ptr_util.h"
hashimotobb42dee2016-01-14 10:13:5612#include "base/run_loop.h"
13#include "base/strings/utf_string_conversions.h"
hashimoto9aea6a152016-02-01 06:27:5214#include "base/synchronization/waitable_event.h"
hashimotobb42dee2016-01-14 10:13:5615#include "chromeos/binder/local_object.h"
16#include "chromeos/binder/service_manager_proxy.h"
17#include "chromeos/binder/transaction_data.h"
18#include "chromeos/binder/transaction_data_reader.h"
19#include "chromeos/binder/writable_transaction_data.h"
20
21namespace binder {
22
23class TestService::TestObject : public LocalObject::TransactionHandler {
24 public:
hashimoto9aea6a152016-02-01 06:27:5225 TestObject()
26 : event_(false /* manual_reset */, false /* initially_signaled */) {
27 VLOG(1) << "Object created: " << this;
28 }
hashimotobb42dee2016-01-14 10:13:5629
30 ~TestObject() override { VLOG(1) << "Object destroyed: " << this; }
31
dcheng0a6e80c2016-04-08 18:37:3832 std::unique_ptr<binder::TransactionData> OnTransact(
hashimotobb42dee2016-01-14 10:13:5633 binder::CommandBroker* command_broker,
34 const binder::TransactionData& data) {
35 VLOG(1) << "Transact code = " << data.GetCode();
36 binder::TransactionDataReader reader(data);
37 switch (data.GetCode()) {
38 case INCREMENT_INT_TRANSACTION: {
39 int32_t arg = 0;
40 reader.ReadInt32(&arg);
dcheng0a6e80c2016-04-08 18:37:3841 std::unique_ptr<binder::WritableTransactionData> reply(
hashimotobb42dee2016-01-14 10:13:5642 new binder::WritableTransactionData());
43 reply->WriteInt32(arg + 1);
44 return std::move(reply);
45 }
hashimoto93582b22016-01-18 05:52:1046 case GET_FD_TRANSACTION: {
47 // Prepare a file.
48 std::string data = GetFileContents();
49 base::ScopedTempDir temp_dir;
50 base::FilePath path;
51 if (!temp_dir.CreateUniqueTempDir() ||
52 !base::CreateTemporaryFileInDir(temp_dir.path(), &path) ||
53 !base::WriteFile(path, data.data(), data.size())) {
54 LOG(ERROR) << "Failed to create a file";
dcheng0a6e80c2016-04-08 18:37:3855 return std::unique_ptr<TransactionData>();
hashimoto93582b22016-01-18 05:52:1056 }
57 // Open the file.
58 base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
59 if (!file.IsValid()) {
60 LOG(ERROR) << "Failed to open the file.";
dcheng0a6e80c2016-04-08 18:37:3861 return std::unique_ptr<TransactionData>();
hashimoto93582b22016-01-18 05:52:1062 }
63 // Return the FD.
64 // The file will be deleted by |temp_dir|, but the FD remains valid
65 // until the receiving process closes it.
dcheng0a6e80c2016-04-08 18:37:3866 std::unique_ptr<binder::WritableTransactionData> reply(
hashimoto93582b22016-01-18 05:52:1067 new binder::WritableTransactionData());
68 reply->WriteFileDescriptor(base::ScopedFD(file.TakePlatformFile()));
69 return std::move(reply);
70 }
hashimoto9aea6a152016-02-01 06:27:5271 case WAIT_TRANSACTION: {
72 event_.Wait();
dcheng0a6e80c2016-04-08 18:37:3873 std::unique_ptr<binder::WritableTransactionData> reply(
hashimoto9aea6a152016-02-01 06:27:5274 new binder::WritableTransactionData());
75 reply->WriteUint32(WAIT_TRANSACTION);
76 return std::move(reply);
77 }
78 case SIGNAL_TRANSACTION: {
79 event_.Signal();
dcheng0a6e80c2016-04-08 18:37:3880 std::unique_ptr<binder::WritableTransactionData> reply(
hashimoto9aea6a152016-02-01 06:27:5281 new binder::WritableTransactionData());
82 reply->WriteUint32(SIGNAL_TRANSACTION);
83 return std::move(reply);
84 }
hashimotobb42dee2016-01-14 10:13:5685 }
dcheng0a6e80c2016-04-08 18:37:3886 return std::unique_ptr<TransactionData>();
hashimotobb42dee2016-01-14 10:13:5687 }
88
89 private:
hashimoto9aea6a152016-02-01 06:27:5290 base::WaitableEvent event_;
91
hashimotobb42dee2016-01-14 10:13:5692 DISALLOW_COPY_AND_ASSIGN(TestObject);
93};
94
95TestService::TestService()
96 : service_name_(base::ASCIIToUTF16("org.chromium.TestService-" +
hashimoto9aea6a152016-02-01 06:27:5297 base::GenerateGUID())),
98 sub_thread_(&main_thread_) {}
hashimotobb42dee2016-01-14 10:13:5699
100TestService::~TestService() {}
101
102bool TestService::StartAndWait() {
hashimoto9aea6a152016-02-01 06:27:52103 if (!main_thread_.Start() || !sub_thread_.Start() ||
104 !main_thread_.WaitUntilThreadStarted() || !main_thread_.initialized() ||
105 !sub_thread_.WaitUntilThreadStarted() || !sub_thread_.initialized()) {
106 LOG(ERROR) << "Failed to start the threads.";
hashimotobb42dee2016-01-14 10:13:56107 return false;
108 }
109 bool result = false;
110 base::RunLoop run_loop;
hashimoto9aea6a152016-02-01 06:27:52111 main_thread_.task_runner()->PostTaskAndReply(
hashimotobb42dee2016-01-14 10:13:56112 FROM_HERE,
113 base::Bind(&TestService::Initialize, base::Unretained(this), &result),
114 run_loop.QuitClosure());
115 run_loop.Run();
116 return result;
117}
118
119void TestService::Stop() {
hashimoto9aea6a152016-02-01 06:27:52120 sub_thread_.Stop();
121 main_thread_.Stop();
hashimotobb42dee2016-01-14 10:13:56122}
123
hashimoto93582b22016-01-18 05:52:10124// static
125std::string TestService::GetFileContents() {
126 return "Test data";
127}
128
hashimotobb42dee2016-01-14 10:13:56129void TestService::Initialize(bool* result) {
130 // Add service.
131 scoped_refptr<LocalObject> object(
dcheng0a6e80c2016-04-08 18:37:38132 new LocalObject(base::WrapUnique(new TestObject)));
hashimoto9aea6a152016-02-01 06:27:52133 *result = ServiceManagerProxy::AddService(main_thread_.command_broker(),
hashimotobb42dee2016-01-14 10:13:56134 service_name_, object, 0);
135}
136
137} // namespace binder