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 auto transactionProxy = RSTransactionProxy::GetInstance();
38 if (transactionProxy != nullptr) {
39 RS_TRACE_NAME("OpenSyncTransaction");
40 ROSEN_LOGI("OpenSyncTransaction");
41 transactionProxy->FlushImplicitTransaction();
42 transactionProxy->StartSyncTransaction();
43 transactionProxy->Begin();
44 isOpenSyncTransaction_ = true;
45 transactionCount_ = 0;
46 parentPid_ = GetRealPid();
47 transactionProxy->StartCloseSyncTransactionFallbackTask(handler, true);
48 }
49 }
50
CloseSyncTransaction(std::shared_ptr<AppExecFwk::EventHandler> handler)51 void RSTransaction::CloseSyncTransaction(std::shared_ptr<AppExecFwk::EventHandler> handler)
52 {
53 auto transactionProxy = RSTransactionProxy::GetInstance();
54 if (transactionProxy != nullptr) {
55 RS_TRACE_NAME_FMT("CloseSyncTransaction syncId: %lu syncCount: %d", syncId_, transactionCount_);
56 ROSEN_LOGI(
57 "CloseSyncTransaction syncId: %{public}" PRIu64 " syncCount: %{public}d", syncId_, transactionCount_);
58 isOpenSyncTransaction_ = false;
59 transactionProxy->MarkTransactionNeedCloseSync(transactionCount_);
60 transactionProxy->SetSyncId(syncId_);
61 transactionProxy->CommitSyncTransaction();
62 transactionProxy->CloseSyncTransaction();
63 transactionProxy->StartCloseSyncTransactionFallbackTask(handler, false);
64 }
65 ResetSyncTransactionInfo();
66 }
67
Begin()68 void RSTransaction::Begin()
69 {
70 auto transactionProxy = RSTransactionProxy::GetInstance();
71 if (transactionProxy != nullptr) {
72 RS_TRACE_NAME("BeginSyncTransaction");
73 ROSEN_LOGI("BeginSyncTransaction");
74 transactionProxy->StartSyncTransaction();
75 transactionProxy->Begin();
76 }
77 }
78
Commit()79 void RSTransaction::Commit()
80 {
81 auto transactionProxy = RSTransactionProxy::GetInstance();
82 if (transactionProxy != nullptr) {
83 RS_TRACE_NAME_FMT(
84 "CommitSyncTransaction syncId: %lu syncCount: %d parentPid: %d", syncId_, transactionCount_, parentPid_);
85 ROSEN_LOGI("CommitSyncTransaction syncId: %{public}" PRIu64 " syncCount: %{public}d parentPid: %{public}d",
86 syncId_, transactionCount_, parentPid_);
87 transactionProxy->SetSyncTransactionNum(transactionCount_);
88 transactionProxy->SetSyncId(syncId_);
89 transactionProxy->SetParentPid(parentPid_);
90 transactionProxy->CommitSyncTransaction();
91 transactionProxy->CloseSyncTransaction();
92 }
93 ResetSyncTransactionInfo();
94 }
95
GenerateSyncId()96 uint64_t RSTransaction::GenerateSyncId()
97 {
98 static pid_t pid_ = GetRealPid();
99 static std::atomic<uint32_t> currentId_ = 0;
100
101 auto currentId = currentId_.fetch_add(1, std::memory_order_relaxed);
102 if (currentId == UINT32_MAX) {
103 // [PLANNING]:process the overflow situations
104 ROSEN_LOGE("Transaction sync Id overflow");
105 }
106
107 // concat two 32-bit numbers to one 64-bit number
108 return ((uint64_t)pid_ << 32) | currentId;
109 }
110
ResetSyncTransactionInfo()111 void RSTransaction::ResetSyncTransactionInfo()
112 {
113 std::unique_lock<std::mutex> lock(mutex_);
114 syncId_ = 0;
115 transactionCount_ = 0;
116 parentPid_ = -1;
117 isOpenSyncTransaction_ = false;
118 }
119
Unmarshalling(Parcel & parcel)120 RSTransaction* RSTransaction::Unmarshalling(Parcel& parcel)
121 {
122 auto rsTransaction = new RSTransaction();
123 if (rsTransaction->UnmarshallingParam(parcel)) {
124 return rsTransaction;
125 }
126 ROSEN_LOGE("RSTransactionData Unmarshalling Failed");
127 delete rsTransaction;
128 return nullptr;
129 }
130
Marshalling(Parcel & parcel) const131 bool RSTransaction::Marshalling(Parcel& parcel) const
132 {
133 if (!parcel.WriteUint64(syncId_)) {
134 ROSEN_LOGE("RSTransaction marshalling synchronous Id failed");
135 return false;
136 }
137 if (!parcel.WriteInt32(duration_)) {
138 ROSEN_LOGE("RSTransaction marshalling duration failed");
139 return false;
140 }
141 if (!parcel.WriteInt32(parentPid_)) {
142 ROSEN_LOGE("RSTransaction marshalling parent pid failed");
143 return false;
144 }
145 if (!parcel.WriteBool(isOpenSyncTransaction_)) {
146 ROSEN_LOGE("RSTransaction marshalling parameter of whether synchronous transaction is open failed");
147 return false;
148 }
149 transactionCount_++;
150 RS_TRACE_NAME_FMT("RSTransaction::Marshalling syncId: %lu syncCount: %d", syncId_, transactionCount_);
151 ROSEN_LOGD("Marshalling syncId: %{public}" PRIu64 " syncCount: %{public}d", syncId_, transactionCount_);
152 return true;
153 }
154
UnmarshallingParam(Parcel & parcel)155 bool RSTransaction::UnmarshallingParam(Parcel& parcel)
156 {
157 if (!parcel.ReadUint64(syncId_)) {
158 ROSEN_LOGE("RSTransaction unmarshallingParam synchronous Id failed");
159 return false;
160 }
161 if (!parcel.ReadInt32(duration_)) {
162 ROSEN_LOGE("RSTransaction unmarshallingParam duration failed");
163 return false;
164 }
165 if (!parcel.ReadInt32(parentPid_)) {
166 ROSEN_LOGE("RSTransaction unmarshallingParam parent pid failed");
167 return false;
168 }
169 if (!parcel.ReadBool(isOpenSyncTransaction_)) {
170 ROSEN_LOGE("RSTransaction unmarshalling parameter of whether synchronous transaction is open failed");
171 }
172 return true;
173 }
174 } // namespace Rosen
175 } // namespace OHOS
176