1 /*
2  * Copyright (c) 2024 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 <iomanip>
16 #include <ctime>
17 #include "media_library_adapter.h"
18 #include "media_library_manager.h"
19 #include "media_log.h"
20 #include "ipc_skeleton.h"
21 #include "media_dfx.h"
22 #include "hitrace/tracechain.h"
23 #include "system_ability_definition.h"
24 #include "iservice_registry.h"
25 
26 namespace {
27     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_RECORDER, "RecorderServer"};
28 }
29 
30 namespace OHOS {
31 namespace Media {
32 namespace MeidaLibraryAdapter {
33 constexpr std::string_view prefix = "VID_";
34 constexpr std::string_view connector = "_";
35 class RecorderPhotoProxy : public PhotoProxy {
36 public:
RecorderPhotoProxy()37     RecorderPhotoProxy() { }
38 
GetDisplayName()39     std::string GetDisplayName()
40     {
41         return GetTitle() + '.' + GetExtension();
42     }
43 
SetDisplayName(const std::string & displayName)44     void SetDisplayName(const std::string &displayName)
45     {
46         displayName_ = displayName;
47     }
48 
GetExtension()49     std::string GetExtension() override
50     {
51         return "mp4";
52     }
53 
GetPhotoId()54     std::string GetPhotoId() override
55     {
56         return "";
57     }
58 
GetDeferredProcType()59     DeferredProcType GetDeferredProcType() override
60     {
61         return DeferredProcType::BACKGROUND;
62     }
63 
GetWidth()64     int32_t GetWidth() override
65     {
66         return 0;
67     }
68 
GetHeight()69     int32_t GetHeight() override
70     {
71         return 0;
72     }
73 
GetFileDataAddr()74     void* GetFileDataAddr() override
75     {
76         return fileDataAddr_;
77     }
78 
GetFileSize()79     size_t GetFileSize() override
80     {
81         return 0;
82     }
83 
Release()84     void Release() override
85     {
86     }
87 
GetFormat()88     PhotoFormat GetFormat() override
89     {
90         return photoFormat_;
91     }
92 
SetFormat(PhotoFormat format)93     void SetFormat(PhotoFormat format)
94     {
95         photoFormat_ = format;
96     }
97 
GetPhotoQuality()98     PhotoQuality GetPhotoQuality() override
99     {
100         return PhotoQuality::HIGH;
101     }
102 
GetLatitude()103     double GetLatitude() override
104     {
105         return 0.0;
106     }
107 
GetLongitude()108     double GetLongitude() override
109     {
110         return 0.0;
111     }
GetTitle()112     std::string GetTitle() override
113     {
114         return displayName_;
115     }
116 
GetShootingMode()117     int32_t GetShootingMode() override
118     {
119         return 0;
120     }
121 
GetBurstKey()122     std::string GetBurstKey() override
123     {
124         return "";
125     }
126 
IsCoverPhoto()127     bool IsCoverPhoto() override
128     {
129         return false;
130     }
131 private:
132     void *fileDataAddr_ = nullptr;
133     std::string displayName_;
134     PhotoFormat photoFormat_ = PhotoFormat::RGBA;
135 };
136 
GetLocaltime(const time_t * clock,struct tm * result)137 struct tm *GetLocaltime(const time_t* clock, struct tm *result)
138 {
139     struct tm *ptr = localtime(clock);
140     if (!ptr) {
141         return nullptr;
142     }
143     *result = *ptr;
144     return result;
145 }
146 
CreateDisplayName()147 std::string CreateDisplayName()
148 {
149     struct tm currentTime;
150     std::string formattedTime = "";
151 
152     auto clock =  std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
153     struct tm* timeResult = GetLocaltime(&clock, &currentTime);
154     int32_t yearWidth = 4;
155     int32_t otherWidth = 2;
156     int32_t startYear = 1900;
157     char placeholder = '0';
158     if (timeResult != nullptr) {
159         std::stringstream ss;
160         ss << prefix << std::setw(yearWidth) << std::setfill(placeholder) << currentTime.tm_year + startYear
161            << std::setw(otherWidth) << std::setfill(placeholder) << (currentTime.tm_mon + 1)
162            << std::setw(otherWidth) << std::setfill(placeholder) << currentTime.tm_mday
163            << connector << std::setw(otherWidth) << std::setfill(placeholder) << currentTime.tm_hour
164            << std::setw(otherWidth) << std::setfill(placeholder) << currentTime.tm_min
165            << std::setw(otherWidth) << std::setfill(placeholder) << currentTime.tm_sec;
166         formattedTime = ss.str();
167     } else {
168         MEDIA_LOGE("Failed to get current time.");
169     }
170     return formattedTime;
171 }
172 
CreateMediaLibrary(int32_t & fd,std::string & uri)173 bool CreateMediaLibrary(int32_t &fd, std::string &uri)
174 {
175     MediaTrace trace("RecorderServer::CreateMediaLibrary");
176     MEDIA_LOGI("RecorderServer::CreateMediaLibrary");
177     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
178     CHECK_AND_RETURN_RET_LOG(samgr != nullptr, false, "Failed to get System ability manager");
179     auto object = samgr->GetSystemAbility(PLAYER_DISTRIBUTED_SERVICE_ID);
180     CHECK_AND_RETURN_RET_LOG(object != nullptr, false, "object is null");
181     auto mediaLibraryManager = Media::MediaLibraryManager::GetMediaLibraryManager();
182     CHECK_AND_RETURN_RET_LOG(mediaLibraryManager != nullptr, false,
183         "Error to init mediaLibraryManager");
184     mediaLibraryManager->InitMediaLibraryManager(object);
185     const static int32_t INVALID_UID = -1;
186     const static int32_t BASE_USER_RANGE = 200000;
187     int32_t uid = IPCSkeleton::GetCallingUid();
188     if (uid <= INVALID_UID) {
189         MEDIA_LOGD("Get INVALID_UID UID %{public}d", uid);
190     }
191     int32_t userId = uid / BASE_USER_RANGE;
192     MEDIA_LOGD("get uid:%{public}d, userId:%{public}d, tokenId:%{public}d", uid, userId,
193         IPCSkeleton::GetCallingTokenID());
194 
195     auto photoAssetProxy = mediaLibraryManager->CreatePhotoAssetProxy(CameraShotType::VIDEO, uid, userId);
196     sptr<RecorderPhotoProxy> recorderPhotoProxy = new(std::nothrow) RecorderPhotoProxy();
197     CHECK_AND_RETURN_RET_LOG(recorderPhotoProxy != nullptr, false,
198         "Error to create recorderPhotoProxy");
199     recorderPhotoProxy->SetDisplayName(CreateDisplayName());
200     photoAssetProxy->AddPhotoProxy((sptr<PhotoProxy>&)recorderPhotoProxy);
201     uri = photoAssetProxy->GetPhotoAssetUri();
202     MEDIA_LOGD("video uri:%{public}s", uri.c_str());
203     fd = mediaLibraryManager->OpenAsset(uri, "rw");
204     return true;
205 }
206 } // namespace MeidaLibraryAdapter
207 } // namespace Media
208 } // namespace OHOS