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