1 /*
2 * Copyright (C) 2022-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 #define MLOG_TAG "Thumbnail"
16
17 #include "thumbnail_generation_post_process.h"
18
19 #include "asset_accurate_refresh.h"
20 #include "dfx_utils.h"
21 #include "medialibrary_errno.h"
22 #include "medialibrary_notify.h"
23 #include "medialibrary_tracer.h"
24 #include "media_log.h"
25 #include "result_set_utils.h"
26 #include "thumbnail_utils.h"
27 #include "refresh_business_name.h"
28
29 using namespace std;
30 using namespace OHOS::NativeRdb;
31
32 namespace OHOS {
33 namespace Media {
34
PostProcess(ThumbnailData & data,const ThumbRdbOpt & opts)35 int32_t ThumbnailGenerationPostProcess::PostProcess(ThumbnailData& data, const ThumbRdbOpt& opts)
36 {
37 CHECK_AND_RETURN_RET_INFO_LOG(!data.rdbUpdateCache.IsEmpty(), E_OK, "RdbUpdateCache is empty, no need update.");
38 int32_t err = E_OK;
39 bool hasGeneratedThumb = HasGeneratedThumb(data);
40 MEDIA_INFO_LOG("HasGeneratedThumb: %{public}d", hasGeneratedThumb);
41 if (!hasGeneratedThumb) {
42 err = UpdateCachedRdbValue(data, opts);
43 CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "UpdateCachedRdbValue failed. err: %{public}d", err);
44 data.rdbUpdateCache.Clear();
45 return E_OK;
46 }
47
48 // 必须在更新数据库前获取通知类型
49 NotifyType notifyType;
50 err = GetNotifyType(data, opts, notifyType);
51 CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "GetNotifyType failed. err: %{public}d", err);
52
53 AccurateRefresh::AssetAccurateRefresh assetRefresh(AccurateRefresh::THUMBNAIL_GENERATION_BUSSINESS_NAME);
54 int32_t changedRows;
55 RdbPredicates predicates(PhotoColumn::PHOTOS_TABLE);
56 predicates.EqualTo(PhotoColumn::MEDIA_ID, data.id);
57 auto ret = assetRefresh.Update(changedRows, data.rdbUpdateCache, predicates);
58 CHECK_AND_RETURN_RET_LOG(ret == E_OK, ret, "AssetRefresh.Update failed. err: %{public}d", ret);
59 data.rdbUpdateCache.Clear();
60 ret = assetRefresh.Notify();
61 CHECK_AND_RETURN_RET_LOG(ret == E_OK, ret, "Notify failed. err: %{public}d", ret);
62
63 err = Notify(data, notifyType);
64 CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "Notify failed. err: %{public}d", err);
65 return E_OK;
66 }
67
UpdateCachedRdbValue(ThumbnailData & data,const ThumbRdbOpt & opts)68 int32_t ThumbnailGenerationPostProcess::UpdateCachedRdbValue(ThumbnailData& data, const ThumbRdbOpt& opts)
69 {
70 const string& photosTable = PhotoColumn::PHOTOS_TABLE;
71 CHECK_AND_RETURN_RET_LOG(opts.store != nullptr, E_ERR, "RdbStore is nullptr");
72 CHECK_AND_RETURN_RET_LOG(opts.table == photosTable, false,
73 "Not %{public}s table, table: %{public}s", photosTable.c_str(), opts.table.c_str());
74 MediaLibraryTracer tracer;
75 tracer.Start("UpdateCachedRdbValue opts.store->Update");
76 int32_t changedRows;
77 int32_t err = opts.store->Update(changedRows, photosTable,
78 data.rdbUpdateCache, MEDIA_DATA_DB_ID + " = ?", { data.id });
79 CHECK_AND_RETURN_RET_LOG(err == E_OK, err, "UpdateCachedRdbValue failed. table: %{public}s, err: %{public}d",
80 photosTable.c_str(), err);
81 CHECK_AND_RETURN_RET_LOG(changedRows != 0, E_ERR, "Rdb has no data, id:%{public}s, DeleteThumbnail:%{public}d",
82 data.id.c_str(), ThumbnailUtils::DeleteThumbnailDirAndAstc(opts, data));
83 return E_OK;
84 }
85
Notify(const ThumbnailData & data,const NotifyType notifyType)86 int32_t ThumbnailGenerationPostProcess::Notify(const ThumbnailData& data, const NotifyType notifyType)
87 {
88 auto watch = MediaLibraryNotify::GetInstance();
89 CHECK_AND_RETURN_RET_LOG(watch != nullptr, E_ERR, "SendThumbNotify watch is nullptr");
90 watch->Notify(data.fileUri, notifyType);
91 MEDIA_INFO_LOG("ThumbnailGenerationPostProcess::Notify() "
92 "fileUri: %{public}s, notifyType: %{public}d", data.fileUri.c_str(), notifyType);
93 return E_OK;
94 }
95
96
GetNotifyType(const ThumbnailData & data,const ThumbRdbOpt & opts,NotifyType & notifyType)97 int32_t ThumbnailGenerationPostProcess::GetNotifyType(const ThumbnailData& data,
98 const ThumbRdbOpt& opts, NotifyType& notifyType)
99 {
100 int32_t err = E_OK;
101 CHECK_AND_RETURN_RET_LOG(opts.store != nullptr, E_ERR, "RdbStore is nullptr");
102 CHECK_AND_RETURN_RET_LOG(!data.id.empty(), E_ERR, "Data.id is empty");
103
104 vector<string> columns = { PhotoColumn::PHOTO_THUMBNAIL_VISIBLE };
105 string strQueryCondition = MEDIA_DATA_DB_ID + " = " + data.id;
106 RdbPredicates rdbPredicates(PhotoColumn::PHOTOS_TABLE);
107 rdbPredicates.SetWhereClause(strQueryCondition);
108
109 auto resultSet = opts.store->QueryByStep(rdbPredicates, columns);
110 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_ERR, "QueryByStep() result is null");
111 auto ret = resultSet->GoToFirstRow();
112 CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, E_ERR, "ResultSet->GoToFirstRow() failed");
113 int32_t thumbnailVisible = GetInt32Val(PhotoColumn::PHOTO_THUMBNAIL_VISIBLE, resultSet);
114
115 notifyType = thumbnailVisible > 0 ? NotifyType::NOTIFY_THUMB_UPDATE : NotifyType::NOTIFY_THUMB_ADD;
116 return E_OK;
117 }
118
HasGeneratedThumb(const ThumbnailData & data)119 bool ThumbnailGenerationPostProcess::HasGeneratedThumb(const ThumbnailData& data)
120 {
121 ValueObject valueObject;
122 bool hasThumbReadyColumn = data.rdbUpdateCache.GetObject(PhotoColumn::PHOTO_THUMBNAIL_READY, valueObject);
123 CHECK_AND_RETURN_RET_INFO_LOG(hasThumbReadyColumn, false, "Do not cache thumbnail_ready value in photos table");
124
125 int64_t thumbReady;
126 valueObject.GetLong(thumbReady);
127 return thumbReady != static_cast<int64_t>(ThumbnailReady::GENERATE_THUMB_RETRY);
128 }
129
130 } // namespace Media
131 } // namespace OHOS