• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 
16 #include <algorithm>
17 #include <gtest/gtest.h>
18 #include <thread>
19 #include <tuple>
20 
21 #include "accesstoken_kit_mock.h"
22 #include "ffrt/ffrt_utils.h"
23 #include "pasteboard_disposable_manager.h"
24 #include "pasteboard_error.h"
25 #include "pasteboard_hilog.h"
26 
27 namespace OHOS::MiscServices {
28 using namespace testing::ext;
29 using testing::NiceMock;
30 
31 constexpr int32_t INVALID_VALUE = -1;
32 
33 class PasteboardDisposableManagerTest : public testing::Test {
34 public:
35     static void SetUpTestCase(void);
36     static void TearDownTestCase(void);
37     void SetUp();
38     void TearDown();
39 };
40 
SetUpTestCase()41 void PasteboardDisposableManagerTest::SetUpTestCase()
42 {
43 }
44 
TearDownTestCase()45 void PasteboardDisposableManagerTest::TearDownTestCase()
46 {
47 }
48 
SetUp()49 void PasteboardDisposableManagerTest::SetUp()
50 {
51 }
52 
TearDown()53 void PasteboardDisposableManagerTest::TearDown()
54 {
55     FFRTPool::Clear();
56     DisposableManager::GetInstance().disposableInfoList_.clear();
57 }
58 
59 class DisposableObserverImpl : public IPasteboardDisposableObserver {
60 public:
OnTextReceived(const std::string & text,int32_t errCode)61     void OnTextReceived(const std::string &text, int32_t errCode) override
62     {
63         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "text=%{public}s, errCode=%{public}d", text.c_str(), errCode);
64         text_ = text;
65         errCode_ = errCode;
66     }
67 
AsObject()68     sptr<IRemoteObject> AsObject() override
69     {
70         return nullptr;
71     }
72 
73     std::string text_;
74     int32_t errCode_ = INVALID_VALUE;
75 };
76 
77 class DelayGetterImpl : public IPasteboardDelayGetter {
78 public:
GetPasteData(const std::string & type,PasteData & data)79     void GetPasteData(const std::string &type, PasteData &data) override
80     {
81         (void)type;
82         data.AddTextRecord(text_);
83     }
84 
GetUnifiedData(const std::string & type,UDMF::UnifiedData & data)85     void GetUnifiedData(const std::string &type, UDMF::UnifiedData &data) override
86     {
87         (void)type;
88         (void)data;
89     }
90 
AsObject()91     sptr<IRemoteObject> AsObject() override
92     {
93         return nullptr;
94     }
95 
96     std::string text_;
97 };
98 
99 class EntryGetterImpl : public IPasteboardEntryGetter {
100 public:
GetRecordValueByType(uint32_t recordId,PasteDataEntry & entry)101     int32_t GetRecordValueByType(uint32_t recordId, PasteDataEntry &entry) override
102     {
103         constexpr uint32_t recordId1 = 1;
104         constexpr uint32_t recordId2 = 2;
105         if (recordId == recordId1) {
106             return static_cast<int32_t>(PasteboardError::INVALID_RECORD_ID);
107         }
108         if (recordId == recordId2) {
109             return static_cast<int32_t>(PasteboardError::E_OK);
110         }
111         entry.SetValue(text_);
112         return static_cast<int32_t>(PasteboardError::E_OK);
113     }
114 
AsObject()115     sptr<IRemoteObject> AsObject() override
116     {
117         return nullptr;
118     }
119 
120     std::string text_;
121 };
122 
operator ==(const DisposableInfo & lhs,const DisposableInfo & rhs)123 bool operator==(const DisposableInfo &lhs, const DisposableInfo &rhs)
124 {
125     return std::tie(lhs.pid, lhs.tokenId, lhs.targetBundleName, lhs.type, lhs.maxLen)
126         == std::tie(rhs.pid, rhs.tokenId, rhs.targetBundleName, rhs.type, rhs.maxLen);
127 }
128 
129 /**
130  * @tc.name: AddDisposableInfoTest001
131  * @tc.desc: should return INVALID_PARAM_ERROR when param invalid
132  * @tc.type: FUNC
133  */
134 HWTEST_F(PasteboardDisposableManagerTest, AddDisposableInfoTest001, TestSize.Level0)
135 {
136     pid_t pid = 1;
137     uint32_t tokenId = 100;
138     std::string targetBundleName = "bundleName";
139     DisposableType type = DisposableType::MAX;
140     uint32_t maxLen = 1000;
141     sptr<IPasteboardDisposableObserver> observer = nullptr;
142     DisposableInfo info(pid, tokenId, targetBundleName, type, maxLen, observer);
143     int32_t ret = DisposableManager::GetInstance().AddDisposableInfo(info);
144     ASSERT_EQ(ret, static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR));
145 
146     info.observer = sptr<DisposableObserverImpl>::MakeSptr();
147     ret = DisposableManager::GetInstance().AddDisposableInfo(info);
148     ASSERT_EQ(ret, static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR));
149 }
150 
151 /**
152  * @tc.name: AddDisposableInfoTest002
153  * @tc.desc: should return PERMISSION_VERIFICATION_ERROR when verify permission denied
154  *           should return E_OK when verify permission granted
155  * @tc.type: FUNC
156  */
157 HWTEST_F(PasteboardDisposableManagerTest, AddDisposableInfoTest002, TestSize.Level0)
158 {
159     NiceMock<Security::AccessToken::AccessTokenKitMock> accessTokenMock;
160     EXPECT_CALL(accessTokenMock, VerifyAccessToken)
161         .WillOnce(testing::Return(Security::AccessToken::PermissionState::PERMISSION_DENIED))
162         .WillOnce(testing::Return(Security::AccessToken::PermissionState::PERMISSION_GRANTED));
163 
164     pid_t pid = 1;
165     uint32_t tokenId = 100;
166     std::string targetBundleName = "bundleName";
167     DisposableType type = DisposableType::PLAIN_TEXT;
168     uint32_t maxLen = 1000;
169     sptr<IPasteboardDisposableObserver> observer = sptr<DisposableObserverImpl>::MakeSptr();
170     DisposableInfo info(pid, tokenId, targetBundleName, type, maxLen, observer);
171     int32_t ret = DisposableManager::GetInstance().AddDisposableInfo(info);
172     ASSERT_EQ(ret, static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR));
173 
174     ret = DisposableManager::GetInstance().AddDisposableInfo(info);
175     ASSERT_EQ(ret, static_cast<int32_t>(PasteboardError::E_OK));
176     auto infoList = DisposableManager::GetInstance().disposableInfoList_;
177     ASSERT_EQ(infoList.size(), 1);
178     EXPECT_EQ(infoList[0], info);
179 }
180 
181 /**
182  * @tc.name: AddDisposableInfoTest003
183  * @tc.desc: should update info when called twice with same pid before timeout
184  *           should append info when called twice with diff pid before timeout
185  * @tc.type: FUNC
186  */
187 HWTEST_F(PasteboardDisposableManagerTest, AddDisposableInfoTest003, TestSize.Level0)
188 {
189     NiceMock<Security::AccessToken::AccessTokenKitMock> accessTokenMock;
190     EXPECT_CALL(accessTokenMock, VerifyAccessToken)
191         .WillRepeatedly(testing::Return(Security::AccessToken::PermissionState::PERMISSION_GRANTED));
192 
193     pid_t pid = 1;
194     uint32_t tokenId = 100;
195     std::string targetBundleName = "bundleName";
196     DisposableType type = DisposableType::PLAIN_TEXT;
197     uint32_t maxLen = 1000;
198     sptr<IPasteboardDisposableObserver> observer = sptr<DisposableObserverImpl>::MakeSptr();
199     DisposableInfo info(pid, tokenId, targetBundleName, type, maxLen, observer);
200     int32_t ret = DisposableManager::GetInstance().AddDisposableInfo(info);
201     ASSERT_EQ(ret, static_cast<int32_t>(PasteboardError::E_OK));
202     auto infoList = DisposableManager::GetInstance().disposableInfoList_;
203     ASSERT_EQ(infoList.size(), 1);
204     EXPECT_EQ(infoList[0], info);
205 
206     DisposableInfo samePid(pid, tokenId + 1, targetBundleName + "1", type, maxLen + 1, observer);
207     ret = DisposableManager::GetInstance().AddDisposableInfo(samePid);
208     ASSERT_EQ(ret, static_cast<int32_t>(PasteboardError::E_OK));
209     infoList = DisposableManager::GetInstance().disposableInfoList_;
210     ASSERT_EQ(infoList.size(), 1);
211     EXPECT_EQ(infoList[0], samePid);
212 
213     DisposableInfo diffPid = info;
214     diffPid.pid += 1;
215     ret = DisposableManager::GetInstance().AddDisposableInfo(diffPid);
216     ASSERT_EQ(ret, static_cast<int32_t>(PasteboardError::E_OK));
217     infoList = DisposableManager::GetInstance().disposableInfoList_;
218     ASSERT_EQ(infoList.size(), 2);
219     EXPECT_EQ(infoList[0], samePid);
220     EXPECT_EQ(infoList[1], diffPid);
221 }
222 
223 /**
224  * @tc.name: AddDisposableInfoTest004
225  * @tc.desc: should callback ERR_TIMEOUT when timeout
226  *           should clear info after timeout
227  * @tc.type: FUNC
228  */
229 HWTEST_F(PasteboardDisposableManagerTest, AddDisposableInfoTest004, TestSize.Level0)
230 {
231     NiceMock<Security::AccessToken::AccessTokenKitMock> accessTokenMock;
232     EXPECT_CALL(accessTokenMock, VerifyAccessToken)
233         .WillRepeatedly(testing::Return(Security::AccessToken::PermissionState::PERMISSION_GRANTED));
234 
235     pid_t pid = 1;
236     uint32_t tokenId = 100;
237     std::string targetBundleName = "bundleName";
238     DisposableType type = DisposableType::PLAIN_TEXT;
239     uint32_t maxLen = 1000;
240     sptr<DisposableObserverImpl> observer = sptr<DisposableObserverImpl>::MakeSptr();
241     DisposableInfo info(pid, tokenId, targetBundleName, type, maxLen, observer);
242     int32_t ret = DisposableManager::GetInstance().AddDisposableInfo(info);
243     ASSERT_EQ(ret, static_cast<int32_t>(PasteboardError::E_OK));
244     auto infoList = DisposableManager::GetInstance().disposableInfoList_;
245     ASSERT_EQ(infoList.size(), 1);
246     EXPECT_EQ(infoList[0], info);
247 
248     std::this_thread::sleep_for(std::chrono::seconds(1));
249     EXPECT_EQ(observer->errCode_, IPasteboardDisposableObserver::ERR_TIMEOUT);
250     EXPECT_STREQ(observer->text_.c_str(), "");
251     infoList = DisposableManager::GetInstance().disposableInfoList_;
252     EXPECT_EQ(infoList.size(), 0);
253 }
254 
255 /**
256  * @tc.name: RemoveDisposableInfoTest001
257  * @tc.desc: should do nothing when pid not find
258  *           should remove info & not callback when pid find but observer is null
259  *           should remove info & callback ERR_TIMEOUT when pid find & observer not null
260  * @tc.type: FUNC
261  */
262 HWTEST_F(PasteboardDisposableManagerTest, RemoveDisposableInfoTest001, TestSize.Level0)
263 {
264     pid_t pid = 1;
265     DisposableManager::GetInstance().RemoveDisposableInfo(pid, false);
266 
267     DisposableInfo info(pid, 1, "bundleName", DisposableType::PLAIN_TEXT, 1, nullptr);
268     DisposableManager::GetInstance().disposableInfoList_ = {info};
269     DisposableManager::GetInstance().RemoveDisposableInfo(pid, false);
270     EXPECT_TRUE(DisposableManager::GetInstance().disposableInfoList_.empty());
271 
272     DisposableManager::GetInstance().disposableInfoList_ = {info};
273     DisposableManager::GetInstance().RemoveDisposableInfo(pid, true);
274     EXPECT_TRUE(DisposableManager::GetInstance().disposableInfoList_.empty());
275 
276     sptr<DisposableObserverImpl> observer = sptr<DisposableObserverImpl>::MakeSptr();
277     info.observer = observer;
278     DisposableManager::GetInstance().disposableInfoList_ = {info};
279     DisposableManager::GetInstance().RemoveDisposableInfo(pid, false);
280     EXPECT_TRUE(DisposableManager::GetInstance().disposableInfoList_.empty());
281     EXPECT_EQ(observer->errCode_, INVALID_VALUE);
282 
283     DisposableManager::GetInstance().disposableInfoList_ = {info};
284     DisposableManager::GetInstance().RemoveDisposableInfo(pid, true);
285     EXPECT_TRUE(DisposableManager::GetInstance().disposableInfoList_.empty());
286     EXPECT_EQ(observer->errCode_, IPasteboardDisposableObserver::ERR_TIMEOUT);
287 }
288 
289 /**
290  * @tc.name: TryProcessDisposableDataTest001
291  * @tc.desc: should remove info but not callback when observer is null
292  *           should remove info & callback ERR_TARGET_MISMATCH when bundleName missmatch & observer not null
293  * @tc.type: FUNC
294  */
295 HWTEST_F(PasteboardDisposableManagerTest, TryProcessDisposableDataTest001, TestSize.Level0)
296 {
297     NiceMock<Security::AccessToken::AccessTokenKitMock> accessTokenMock;
298     EXPECT_CALL(accessTokenMock, VerifyAccessToken)
299         .WillRepeatedly(testing::Return(Security::AccessToken::PermissionState::PERMISSION_GRANTED));
300 
301     PasteData pasteData;
302     std::string bundleName = "1";
303     sptr<DisposableObserverImpl> observer = sptr<DisposableObserverImpl>::MakeSptr();
304     DisposableInfo infoMatched(1, 1, bundleName, DisposableType::PLAIN_TEXT, 1, nullptr);
305     DisposableInfo infoNoMatch(1, 1, "2", DisposableType::PLAIN_TEXT, 1, nullptr);
306 
307     DisposableManager::GetInstance().disposableInfoList_ = {};
308     bool ret = DisposableManager::GetInstance().TryProcessDisposableData(bundleName, pasteData, nullptr, nullptr);
309     EXPECT_FALSE(ret);
310 
311     DisposableManager::GetInstance().disposableInfoList_ = {infoMatched};
312     ret = DisposableManager::GetInstance().TryProcessDisposableData(bundleName, pasteData, nullptr, nullptr);
313     EXPECT_TRUE(ret);
314     EXPECT_TRUE(DisposableManager::GetInstance().disposableInfoList_.empty());
315 
316     DisposableManager::GetInstance().disposableInfoList_ = {infoNoMatch};
317     ret = DisposableManager::GetInstance().TryProcessDisposableData(bundleName, pasteData, nullptr, nullptr);
318     EXPECT_FALSE(ret);
319     EXPECT_TRUE(DisposableManager::GetInstance().disposableInfoList_.empty());
320 
321     infoNoMatch.observer = observer;
322     DisposableManager::GetInstance().disposableInfoList_ = {infoMatched, infoNoMatch};
323     ret = DisposableManager::GetInstance().TryProcessDisposableData(bundleName, pasteData, nullptr, nullptr);
324     EXPECT_TRUE(ret);
325     EXPECT_TRUE(DisposableManager::GetInstance().disposableInfoList_.empty());
326     EXPECT_EQ(observer->errCode_, IPasteboardDisposableObserver::ERR_TARGET_MISMATCH);
327 }
328 
329 /**
330  * @tc.name: TryProcessDisposableDataTest002
331  * @tc.desc: should callback ERR_NO_PERMISSION without text when verify permission denied
332  *           should callback ERR_TYPE_NOT_SUPPORT without text when type not support
333  *           should callback ERR_NO_TEXT without text when paste data has no text
334  * @tc.type: FUNC
335  */
336 HWTEST_F(PasteboardDisposableManagerTest, TryProcessDisposableDataTest002, TestSize.Level0)
337 {
338     NiceMock<Security::AccessToken::AccessTokenKitMock> accessTokenMock;
339     EXPECT_CALL(accessTokenMock, VerifyAccessToken)
340         .WillOnce(testing::Return(Security::AccessToken::PermissionState::PERMISSION_DENIED))
341         .WillRepeatedly(testing::Return(Security::AccessToken::PermissionState::PERMISSION_GRANTED));
342 
343     PasteData pasteData;
344     std::string bundleName = "1";
345     sptr<DisposableObserverImpl> observer1 = nullptr;
346     sptr<DisposableObserverImpl> observer2 = sptr<DisposableObserverImpl>::MakeSptr();
347     sptr<DisposableObserverImpl> observer3 = sptr<DisposableObserverImpl>::MakeSptr();
348     sptr<DisposableObserverImpl> observer4 = sptr<DisposableObserverImpl>::MakeSptr();
349     DisposableInfo info1(1, 1, bundleName, DisposableType::PLAIN_TEXT, 1, observer1);
350     DisposableInfo info2(1, 1, bundleName, DisposableType::PLAIN_TEXT, 1, observer2);
351     DisposableInfo info3(1, 1, bundleName, DisposableType::MAX, 1, observer3);
352     DisposableInfo info4(1, 1, bundleName, DisposableType::PLAIN_TEXT, 1, observer4);
353 
354     DisposableManager::GetInstance().disposableInfoList_ = {info1, info2, info3, info4};
355     bool ret = DisposableManager::GetInstance().TryProcessDisposableData(bundleName, pasteData, nullptr, nullptr);
356     EXPECT_TRUE(ret);
357     EXPECT_EQ(observer2->errCode_, IPasteboardDisposableObserver::ERR_NO_PERMISSION);
358     EXPECT_EQ(observer3->errCode_, IPasteboardDisposableObserver::ERR_TYPE_NOT_SUPPORT);
359     EXPECT_EQ(observer4->errCode_, IPasteboardDisposableObserver::ERR_NO_TEXT);
360 }
361 
362 /**
363  * @tc.name: TryProcessDisposableDataTest003
364  * @tc.desc: should callback ERR_LENGTH_MISMATCH without text when paste data text length > maxLen
365  *           else should callback ERR_OK with text
366  * @tc.type: FUNC
367  */
368 HWTEST_F(PasteboardDisposableManagerTest, TryProcessDisposableDataTest003, TestSize.Level0)
369 {
370     NiceMock<Security::AccessToken::AccessTokenKitMock> accessTokenMock;
371     EXPECT_CALL(accessTokenMock, VerifyAccessToken)
372         .WillRepeatedly(testing::Return(Security::AccessToken::PermissionState::PERMISSION_GRANTED));
373 
374     std::string bundleName = "1";
375     std::string text = "123456";
376     PasteData pasteData;
377     pasteData.AddTextRecord(text);
378     sptr<DisposableObserverImpl> observer1 = sptr<DisposableObserverImpl>::MakeSptr();
379     sptr<DisposableObserverImpl> observer2 = sptr<DisposableObserverImpl>::MakeSptr();
380     DisposableInfo info1(1, 1, bundleName, DisposableType::PLAIN_TEXT, text.length() - 1, observer1);
381     DisposableInfo info2(1, 1, bundleName, DisposableType::PLAIN_TEXT, text.length() + 1, observer2);
382 
383     DisposableManager::GetInstance().disposableInfoList_ = {info1, info2};
384     bool ret = DisposableManager::GetInstance().TryProcessDisposableData(bundleName, pasteData, nullptr, nullptr);
385     EXPECT_TRUE(ret);
386     EXPECT_EQ(observer1->errCode_, IPasteboardDisposableObserver::ERR_LENGTH_MISMATCH);
387     EXPECT_EQ(observer2->errCode_, IPasteboardDisposableObserver::ERR_OK);
388     EXPECT_STREQ(observer2->text_.c_str(), text.c_str());
389 }
390 
391 /**
392  * @tc.name: TryProcessDisposableDataTest004
393  * @tc.desc: should callback ERR_DATA_IN_APP without text when paste data with ShareOption::InApp
394  *           should callback ERR_OK with text when paste data with ShareOption::LocalDevice
395  *           should callback ERR_OK with text when paste data with ShareOption::CrossDevice
396  * @tc.type: FUNC
397  */
398 HWTEST_F(PasteboardDisposableManagerTest, TryProcessDisposableDataTest004, TestSize.Level0)
399 {
400     NiceMock<Security::AccessToken::AccessTokenKitMock> accessTokenMock;
401     EXPECT_CALL(accessTokenMock, VerifyAccessToken)
402         .WillRepeatedly(testing::Return(Security::AccessToken::PermissionState::PERMISSION_GRANTED));
403 
404     std::string bundleName = "1";
405     std::string text = "123456";
406     PasteData pasteData;
407     pasteData.AddTextRecord(text);
408 
409     size_t loopCnt = 3;
410     ShareOption shareOptions[] = {ShareOption::InApp, ShareOption::LocalDevice, ShareOption::CrossDevice};
411     int32_t errCodes[] = {IPasteboardDisposableObserver::ERR_DATA_IN_APP, IPasteboardDisposableObserver::ERR_OK,
412         IPasteboardDisposableObserver::ERR_OK};
413     std::string texts[] = {"", text, text};
414 
415     for (size_t i = 0; i < loopCnt; ++i) {
416         pasteData.SetShareOption(shareOptions[i]);
417 
418         sptr<DisposableObserverImpl> observer = sptr<DisposableObserverImpl>::MakeSptr();
419         DisposableInfo info(1, 1, bundleName, DisposableType::PLAIN_TEXT, text.length(), observer);
420 
421         DisposableManager::GetInstance().disposableInfoList_ = {info};
422         bool ret = DisposableManager::GetInstance().TryProcessDisposableData(bundleName, pasteData, nullptr, nullptr);
423         EXPECT_TRUE(ret);
424         EXPECT_EQ(observer->errCode_, errCodes[i]);
425         EXPECT_STREQ(observer->text_.c_str(), texts[i].c_str());
426     }
427 }
428 
429 /**
430  * @tc.name: GetPlainTextTest001
431  * @tc.desc: get text from delay getter
432  * @tc.type: FUNC
433  */
434 HWTEST_F(PasteboardDisposableManagerTest, GetPlainTextTest001, TestSize.Level0)
435 {
436     PasteData pasteData;
437     pasteData.SetDelayData(true);
438     std::string text = DisposableManager::GetInstance().GetPlainText(pasteData, nullptr, nullptr);
439     EXPECT_STREQ(text.c_str(), "");
440 
441     sptr<DelayGetterImpl> delayGetter = sptr<DelayGetterImpl>::MakeSptr();
442     delayGetter->text_ = "123456";
443     text = DisposableManager::GetInstance().GetPlainText(pasteData, delayGetter, nullptr);
444     EXPECT_STREQ(text.c_str(), delayGetter->text_.c_str());
445 }
446 
447 /**
448  * @tc.name: GetPlainTextTest002
449  * @tc.desc: get text from entry getter
450  * @tc.type: FUNC
451  */
452 HWTEST_F(PasteboardDisposableManagerTest, GetPlainTextTest002, TestSize.Level0)
453 {
454     constexpr size_t recordNum = 5;
455     std::string text1 = "abcdefghijk";
456     std::string text2 = "123456";
457     std::string text3 = text2 + text1;
458 
459     std::string textUtdId = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::UDType::PLAIN_TEXT);
460     std::string htmlUtdId = UDMF::UtdUtils::GetUtdIdFromUtdEnum(UDMF::UDType::HTML);
461     PasteDataRecord records[recordNum];
462     records[0].AddEntry(textUtdId, std::make_shared<PasteDataEntry>(textUtdId, nullptr));
463     records[0].AddEntry(htmlUtdId, std::make_shared<PasteDataEntry>(htmlUtdId, nullptr));
464     records[1].AddEntry(textUtdId, std::make_shared<PasteDataEntry>(textUtdId, nullptr));
465     records[2].AddEntry(textUtdId, std::make_shared<PasteDataEntry>(textUtdId, nullptr));
466     records[3].AddEntry(textUtdId, std::make_shared<PasteDataEntry>(textUtdId, text1));
467     records[4].AddEntry(htmlUtdId, std::make_shared<PasteDataEntry>(htmlUtdId, text1));
468     PasteData pasteData;
469     pasteData.SetDelayRecord(true);
470     for (auto &record : records) {
471         pasteData.AddRecord(record);
472     }
473     std::reverse(pasteData.records_.begin(), pasteData.records_.end());
474 
475     std::string text = DisposableManager::GetInstance().GetPlainText(pasteData, nullptr, nullptr);
476     EXPECT_STREQ(text.c_str(), text1.c_str());
477 
478     sptr<EntryGetterImpl> entryGetter = sptr<EntryGetterImpl>::MakeSptr();
479     entryGetter->text_ = text2;
480     text = DisposableManager::GetInstance().GetPlainText(pasteData, nullptr, entryGetter);
481     EXPECT_STREQ(text.c_str(), text3.c_str());
482 }
483 } // namespace OHOS::MiscServices
484