• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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