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 #define MLOG_TAG "scan_demo"
16 
17 #include <iostream>
18 #include <unistd.h>
19 #include "accesstoken_kit.h"
20 #include "datashare_helper.h"
21 #include "get_self_permissions.h"
22 #include "iservice_registry.h"
23 #include "ringtone_log.h"
24 #include "ringtone_db_const.h"
25 #include "ringtone_errno.h"
26 #include "nativetoken_kit.h"
27 #include "token_setproc.h"
28 #include "ringtone_asset.h"
29 #include "ringtone_fetch_result.h"
30 
31 using namespace std;
32 using namespace OHOS;
33 using namespace OHOS::Media;
34 using namespace OHOS::DataShare;
35 
36 namespace OHOS {
37 namespace Media {
38 namespace {
39 constexpr int STORAGE_MANAGER_MANAGER_ID = 5003;
40 static const string RINGTONE_LIBRARY_PATH =
41     "/storage/media/local/data/com.ohos.ringtonelibrary.ringtonelibrarydata";
42 std::shared_ptr<DataShare::DataShareHelper> g_dataShareHelper = nullptr;
43 } // namespace
44 } // namespace Media
45 } // namespace OHOS
46 
CreateDataShareHelper(int32_t systemAbilityId)47 static shared_ptr<DataShare::DataShareHelper> CreateDataShareHelper(int32_t systemAbilityId)
48 {
49     RINGTONE_INFO_LOG("CreateDataShareHelper::CreateFileExtHelper ");
50     auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
51     if (saManager == nullptr) {
52         RINGTONE_INFO_LOG("CreateFileExtHelper Get system ability mgr failed.");
53         return nullptr;
54     }
55     auto remoteObj = saManager->GetSystemAbility(systemAbilityId);
56     if (remoteObj == nullptr) {
57         RINGTONE_INFO_LOG("CreateDataShareHelper GetSystemAbility Service Failed.");
58         return nullptr;
59     }
60     return DataShare::DataShareHelper::Creator(remoteObj, RINGTONE_URI);
61 }
62 
SetPermission()63 static int SetPermission()
64 {
65     vector<string> perms;
66     perms.push_back("ohos.permission.WRITE_RINGTONE");
67 
68     uint64_t tokenId = 0;
69     RingtonePermissionUtilsUnitTest::SetAccessTokenPermission("RingtoneScan", perms, tokenId);
70     if (tokenId == 0) {
71         RINGTONE_ERR_LOG("Set Access Token Permisson Failed.");
72         return E_ERR;
73     }
74     return E_SUCCESS;
75 }
76 
RingtoneRead(const unique_ptr<RingtoneAsset> & ringtoneAsset)77 static int RingtoneRead(const unique_ptr<RingtoneAsset> &ringtoneAsset)
78 {
79     if (ringtoneAsset != nullptr && ringtoneAsset->GetPath() != RINGTONE_DEFAULT_STR) {
80         string uriStr = RINGTONE_PATH_URI + RINGTONE_SLASH_CHAR + to_string(ringtoneAsset->GetId());
81         Uri ofUri(uriStr);
82         auto fd = g_dataShareHelper->OpenFile(ofUri, "rw");
83         cout << "OpenFile fd = " << fd << endl;
84         if (fd < 0) {
85             cout << "OpenFile error" << endl;
86             return -fd;
87         }
88         string dataBuffer = "hello world";
89 
90         ssize_t written = write(fd, dataBuffer.c_str(), dataBuffer.size());
91         cout << "OpenFile written = " << written << endl;
92         if (written < 0) {
93             cout << "Failed to copy data buffer, return " << static_cast<int>(written) << endl;
94             close(fd);
95             return E_ERR;
96         }
97         close(fd);
98 
99         fd = g_dataShareHelper->OpenFile(ofUri, "rw");
100         cout << "OpenFile fd = " << fd << endl;
101         if (fd < 0) {
102             cout << "OpenFile error" << endl;
103             return -fd;
104         }
105         const int maxSize = 30;
106         char readBuffer[maxSize];
107         ssize_t readRet = read(fd, readBuffer, maxSize);
108         cout << "OpenFile readRet = " << readRet << endl;
109         if (readRet < 0) {
110             cout << "Failed to copy data buffer, return " << static_cast<int>(readRet) << endl;
111             close(fd);
112             return E_ERR;
113         }
114         if (strcmp(readBuffer, dataBuffer.c_str())) {
115             cout << "Read failure readBuffer != dataBuffer,  readBuffer = " << static_cast<int>(readRet) <<
116                 "written = " << static_cast<int>(written) << endl;
117             close(fd);
118             return E_ERR;
119         }
120         close(fd);
121     }
122     return E_SUCCESS;
123 }
124 
125 /*
126  * Feature: RingtoneScanner
127  * Function: Strat scanner
128  * SubFunction: NA
129  * FunctionPoints: NA
130  * EnvConditions: NA
131  */
main()132 int32_t main()
133 {
134     int ret = SetPermission();
135     if (ret != E_SUCCESS) {
136         return ret;
137     }
138     g_dataShareHelper = CreateDataShareHelper(STORAGE_MANAGER_MANAGER_ID);
139     if (g_dataShareHelper == nullptr) {
140         RINGTONE_ERR_LOG("g_dataShareHelper fail");
141         return ret;
142     }
143 
144     Uri ringtoneUri(RINGTONE_PATH_URI);
145     // Ringtone library Insert api demo
146     const int size = 1022;
147     DataShareValuesBucket valuesBucket;
148     valuesBucket.Put(RINGTONE_COLUMN_DATA, static_cast<string>(RINGTONE_LIBRARY_PATH + "/" +
149         "test_insert_ringtone_library" + to_string(0) + ".ogg"));
150     valuesBucket.Put(RINGTONE_COLUMN_SIZE, static_cast<int64_t>(size));
151     valuesBucket.Put(RINGTONE_COLUMN_DISPLAY_NAME, static_cast<string>("rainning") + ".ogg");
152     valuesBucket.Put(RINGTONE_COLUMN_TITLE, static_cast<string>("rainning"));
153     valuesBucket.Put(RINGTONE_COLUMN_MIME_TYPE, static_cast<string>("ogg"));
154     valuesBucket.Put(RINGTONE_COLUMN_SOURCE_TYPE, static_cast<int>(1));
155     valuesBucket.Put(RINGTONE_COLUMN_SHOT_TONE_TYPE, static_cast<int>(1));
156     g_dataShareHelper->Insert(ringtoneUri, valuesBucket);
157 
158     // Ringtone library Query api demo
159     int errCode = 0;
160     DatashareBusinessError businessError;
161     DataSharePredicates queryPredicates;
162     queryPredicates.EqualTo(RINGTONE_COLUMN_SHOT_TONE_TYPE, to_string(1));
163     vector<string> columns = { {RINGTONE_COLUMN_TONE_ID}, {RINGTONE_COLUMN_DATA}};
164     auto resultSet = g_dataShareHelper->Query(ringtoneUri, queryPredicates, columns, &businessError);
165     errCode = businessError.GetCode();
166     cout << "Query errCode=" << errCode << endl;
167 
168     auto results = make_unique<RingtoneFetchResult<RingtoneAsset>>(move(resultSet));
169     cout << "query count = " << to_string(results->GetCount()) << endl;
170     unique_ptr<RingtoneAsset> ringtoneAsset = results->GetLastObject();
171 
172     ret = RingtoneRead(ringtoneAsset);
173     if (ret != E_SUCCESS) {
174         return E_ERR;
175     }
176 
177     system("rm -rf /storage/media/100/local/data/com.ohos.ringtonelibrary.ringtonelibrarydata/*");
178     return 0;
179 }
180