1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "rs_transaction.h"
16
17 #include "platform/common/rs_log.h"
18 #include "rs_trace.h"
19 #include "sandbox_utils.h"
20 #include "transaction/rs_interfaces.h"
21 #include "transaction/rs_transaction_proxy.h"
22
23 namespace OHOS {
24 namespace Rosen {
25
FlushImplicitTransaction()26 void RSTransaction::FlushImplicitTransaction()
27 {
28 auto transactionProxy = RSTransactionProxy::GetInstance();
29 if (transactionProxy != nullptr) {
30 transactionProxy->FlushImplicitTransaction();
31 }
32 }
33
OpenSyncTransaction(std::shared_ptr<AppExecFwk::EventHandler> handler)34 void RSTransaction::OpenSyncTransaction(std::shared_ptr<AppExecFwk::EventHandler> handler)
35 {
36 syncId_ = GenerateSyncId();
37 if (rsTransactionHandler_ != nullptr) {
38 RS_TRACE_NAME("OpenSyncTransaction");
39 ROSEN_LOGI("OpenSyncTransaction");
40 rsTransactionHandler_->FlushImplicitTransaction();
41 rsTransactionHandler_->StartSyncTransaction();
42 rsTransactionHandler_->Begin();
43 isOpenSyncTransaction_ = true;
44 transactionCount_ = 0;
45 parentPid_ = GetRealPid();
46 rsTransactionHandler_->StartCloseSyncTransactionFallbackTask(handler, true);
47 } else {
48 auto transactionProxy = RSTransactionProxy::GetInstance();
49 if (transactionProxy != nullptr) {
50 RS_TRACE_NAME("OpenSyncTransaction");
51 ROSEN_LOGI("OpenSyncTransaction");
52 transactionProxy->FlushImplicitTransaction();
53 transactionProxy->StartSyncTransaction();
54 transactionProxy->Begin();
55 isOpenSyncTransaction_ = true;
56 transactionCount_ = 0;
57 parentPid_ = GetRealPid();
58 transactionProxy->StartCloseSyncTransactionFallbackTask(handler, true);
59 }
60 }
61 }
62
CloseSyncTransaction(std::shared_ptr<AppExecFwk::EventHandler> handler)63 void RSTransaction::CloseSyncTransaction(std::shared_ptr<AppExecFwk::EventHandler> handler)
64 {
65 if (rsTransactionHandler_ != nullptr) {
66 RS_TRACE_NAME_FMT("CloseSyncTransaction syncId: %lu syncCount: %d", syncId_, transactionCount_);
67 ROSEN_LOGI(
68 "CloseSyncTransaction syncId: %{public}" PRIu64 " syncCount: %{public}d", syncId_, transactionCount_);
69 isOpenSyncTransaction_ = false;
70 rsTransactionHandler_->MarkTransactionNeedCloseSync(transactionCount_);
71 rsTransactionHandler_->SetSyncId(syncId_);
72 rsTransactionHandler_->CommitSyncTransaction();
73 rsTransactionHandler_->CloseSyncTransaction();
74 rsTransactionHandler_->StartCloseSyncTransactionFallbackTask(handler, false);
75 } else {
76 auto transactionProxy = RSTransactionProxy::GetInstance();
77 if (transactionProxy != nullptr) {
78 RS_TRACE_NAME_FMT("CloseSyncTransaction syncId: %lu syncCount: %d", syncId_, transactionCount_);
79 ROSEN_LOGI(
80 "CloseSyncTransaction syncId: %{public}" PRIu64 " syncCount: %{public}d", syncId_, transactionCount_);
81 isOpenSyncTransaction_ = false;
82 transactionProxy->MarkTransactionNeedCloseSync(transactionCount_);
83 transactionProxy->SetSyncId(syncId_);
84 transactionProxy->CommitSyncTransaction();
85 transactionProxy->CloseSyncTransaction();
86 transactionProxy->StartCloseSyncTransactionFallbackTask(handler, false);
87 }
88 }
89 ResetSyncTransactionInfo();
90 }
91
Begin()92 void RSTransaction::Begin()
93 {
94 if (rsTransactionHandler_ != nullptr) {
95 RS_TRACE_NAME("BeginSyncTransaction");
96 ROSEN_LOGI("BeginSyncTransaction");
97 rsTransactionHandler_->StartSyncTransaction();
98 rsTransactionHandler_->Begin();
99 } else {
100 auto transactionProxy = RSTransactionProxy::GetInstance();
101 if (transactionProxy != nullptr) {
102 RS_TRACE_NAME("BeginSyncTransaction");
103 ROSEN_LOGI("BeginSyncTransaction");
104 transactionProxy->StartSyncTransaction();
105 transactionProxy->Begin();
106 }
107 }
108 }
109
Commit()110 void RSTransaction::Commit()
111 {
112 if (rsTransactionHandler_ != nullptr) {
113 RS_TRACE_NAME_FMT(
114 "CommitSyncTransaction syncId: %lu syncCount: %d parentPid: %d", syncId_, transactionCount_, parentPid_);
115 ROSEN_LOGI("CommitSyncTransaction syncId: %{public}" PRIu64 " syncCount: %{public}d parentPid: %{public}d",
116 syncId_, transactionCount_, parentPid_);
117 rsTransactionHandler_->SetSyncTransactionNum(transactionCount_);
118 rsTransactionHandler_->SetSyncId(syncId_);
119 rsTransactionHandler_->SetParentPid(parentPid_);
120 rsTransactionHandler_->CommitSyncTransaction();
121 rsTransactionHandler_->CloseSyncTransaction();
122 } else {
123 auto transactionProxy = RSTransactionProxy::GetInstance();
124 if (transactionProxy != nullptr) {
125 RS_TRACE_NAME_FMT("CommitSyncTransaction syncId: %lu syncCount: %d parentPid: %d", syncId_,
126 transactionCount_, parentPid_);
127 ROSEN_LOGI("CommitSyncTransaction syncId: %{public}" PRIu64 " syncCount: %{public}d parentPid: %{public}d",
128 syncId_, transactionCount_, parentPid_);
129 transactionProxy->SetSyncTransactionNum(transactionCount_);
130 transactionProxy->SetSyncId(syncId_);
131 transactionProxy->SetParentPid(parentPid_);
132 transactionProxy->CommitSyncTransaction();
133 transactionProxy->CloseSyncTransaction();
134 }
135 }
136
137 ResetSyncTransactionInfo();
138 }
139
GenerateSyncId()140 uint64_t RSTransaction::GenerateSyncId()
141 {
142 static pid_t pid_ = GetRealPid();
143 static std::atomic<uint32_t> currentId_ = 0;
144
145 auto currentId = currentId_.fetch_add(1, std::memory_order_relaxed);
146 if (currentId == UINT32_MAX) {
147 // [PLANNING]:process the overflow situations
148 ROSEN_LOGE("Transaction sync Id overflow");
149 }
150
151 // concat two 32-bit numbers to one 64-bit number
152 return ((uint64_t)pid_ << 32) | currentId;
153 }
154
ResetSyncTransactionInfo()155 void RSTransaction::ResetSyncTransactionInfo()
156 {
157 std::unique_lock<std::mutex> lock(mutex_);
158 syncId_ = 0;
159 transactionCount_ = 0;
160 parentPid_ = -1;
161 isOpenSyncTransaction_ = false;
162 }
163
Unmarshalling(Parcel & parcel)164 RSTransaction* RSTransaction::Unmarshalling(Parcel& parcel)
165 {
166 auto rsTransaction = new RSTransaction();
167 if (rsTransaction->UnmarshallingParam(parcel)) {
168 return rsTransaction;
169 }
170 ROSEN_LOGE("RSTransactionData Unmarshalling Failed");
171 delete rsTransaction;
172 return nullptr;
173 }
174
Marshalling(Parcel & parcel) const175 bool RSTransaction::Marshalling(Parcel& parcel) const
176 {
177 if (!parcel.WriteUint64(syncId_)) {
178 ROSEN_LOGE("RSTransaction marshalling synchronous Id failed");
179 return false;
180 }
181 if (!parcel.WriteInt32(duration_)) {
182 ROSEN_LOGE("RSTransaction marshalling duration failed");
183 return false;
184 }
185 if (!parcel.WriteInt32(parentPid_)) {
186 ROSEN_LOGE("RSTransaction marshalling parent pid failed");
187 return false;
188 }
189 if (!parcel.WriteBool(isOpenSyncTransaction_)) {
190 ROSEN_LOGE("RSTransaction marshalling parameter of whether synchronous transaction is open failed");
191 return false;
192 }
193 transactionCount_++;
194 RS_TRACE_NAME_FMT("RSTransaction::Marshalling syncId: %lu syncCount: %d", syncId_, transactionCount_);
195 ROSEN_LOGD("Marshalling syncId: %{public}" PRIu64 " syncCount: %{public}d", syncId_, transactionCount_);
196 return true;
197 }
198
UnmarshallingParam(Parcel & parcel)199 bool RSTransaction::UnmarshallingParam(Parcel& parcel)
200 {
201 if (!parcel.ReadUint64(syncId_)) {
202 ROSEN_LOGE("RSTransaction unmarshallingParam synchronous Id failed");
203 return false;
204 }
205 if (!parcel.ReadInt32(duration_)) {
206 ROSEN_LOGE("RSTransaction unmarshallingParam duration failed");
207 return false;
208 }
209 if (!parcel.ReadInt32(parentPid_)) {
210 ROSEN_LOGE("RSTransaction unmarshallingParam parent pid failed");
211 return false;
212 }
213 if (!parcel.ReadBool(isOpenSyncTransaction_)) {
214 ROSEN_LOGE("RSTransaction unmarshalling parameter of whether synchronous transaction is open failed");
215 }
216 return true;
217 }
218 } // namespace Rosen
219 } // namespace OHOS
220