• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "reminder_store.h"
17 
18 #include <filesystem>
19 #include <sstream>
20 #include <sys/stat.h>
21 #include <unistd.h>
22 
23 #include "ability_context.h"
24 #include "ans_log_wrapper.h"
25 #include "reminder_request_alarm.h"
26 #include "reminder_request_calendar.h"
27 #include "reminder_request_timer.h"
28 
29 namespace OHOS {
30 namespace Notification {
31 namespace {
32 const std::string REMINDER_DB_DIR = "/data/system_ce/ans_standard/";
33 const std::string REMINDER_DB_NAME = "reminder.db";
34 const std::string REMINDER_DB_TABLE = "reminder";
35 const uint32_t REMINDER_RDB_VERSION = 1;
36 const int32_t STATE_FAIL = -1;
37 std::vector<std::string> columns;
38 }
39 
40 const int32_t ReminderStore::STATE_OK = 0;
41 
OnCreate(NativeRdb::RdbStore & store)42 int32_t ReminderStore::ReminderStoreDataCallBack::OnCreate(NativeRdb::RdbStore &store)
43 {
44     ANSR_LOGD("Create table.");
45     std::string CREATE_REMINDER_TABLE = "CREATE TABLE IF NOT EXISTS " + REMINDER_DB_TABLE + " ("
46         + ReminderRequest::sqlOfAddColumns + ")";
47     ANSR_LOGD("CreateTable:%{public}s", CREATE_REMINDER_TABLE.c_str());
48     return store.ExecuteSql(CREATE_REMINDER_TABLE);
49 }
50 
OnUpgrade(NativeRdb::RdbStore & store,int32_t oldVersion,int32_t newVersion)51 int32_t ReminderStore::ReminderStoreDataCallBack::OnUpgrade(
52     NativeRdb::RdbStore &store, int32_t oldVersion, int32_t newVersion)
53 {
54     return NativeRdb::E_OK;
55 }
56 
Init()57 int32_t ReminderStore::Init()
58 {
59     ANSR_LOGD("Reminder store init.");
60     int32_t errCode(STATE_FAIL);
61 
62     if (access(REMINDER_DB_DIR.c_str(), F_OK) != 0) {
63         int createDir = mkdir(REMINDER_DB_DIR.c_str(), S_IRWXU);
64         if (createDir != 0) {
65             ANSR_LOGE("Failed to create directory %{public}s", REMINDER_DB_DIR.c_str());
66             return errCode;
67         }
68     }
69 
70     ReminderRequest::InitDbColumns();
71     ReminderRequestCalendar::InitDbColumns();
72     ReminderRequestAlarm::InitDbColumns();
73     columns.insert(columns.begin(),
74         ReminderRequest::columns.begin(), ReminderRequest::columns.end());
75 
76     std::string dbConfig = REMINDER_DB_DIR + REMINDER_DB_NAME;
77     NativeRdb::RdbStoreConfig config_(dbConfig);
78     ReminderStoreDataCallBack rdbDataCallBack_;
79     rdbStore_ = NativeRdb::RdbHelper::GetRdbStore(config_, REMINDER_RDB_VERSION, rdbDataCallBack_, errCode);
80     if (rdbStore_ == nullptr) {
81         ANSR_LOGE("ReminderStore init fail, errCode %{public}d.", errCode);
82         return errCode;
83     }
84     return ReminderStore::InitData();
85 }
86 
InitData()87 int32_t ReminderStore::InitData()
88 {
89     ANSR_LOGD("Reminder data init.");
90     std::string deleteCondition = ReminderRequest::IS_EXPIRED + " is true";
91     ReminderStore::Delete(deleteCondition);
92 
93     int32_t statusChangedRows = STATE_FAIL;
94     NativeRdb::ValuesBucket statusValues;
95     statusValues.PutInt(ReminderRequest::STATE, ReminderRequest::REMINDER_STATUS_INACTIVE);
96     int32_t statusResult = rdbStore_->Update(statusChangedRows, REMINDER_DB_TABLE, statusValues);
97     ANSR_LOGD("Change status to inactive, changed rows: %{public}d.", statusChangedRows);
98     if (statusResult != NativeRdb::E_OK) {
99         ANSR_LOGE("Init data failed.");
100         return STATE_FAIL;
101     }
102 
103     int32_t activeChangedRows = STATE_FAIL;
104     NativeRdb::ValuesBucket activeValues;
105     activeValues.PutString(ReminderRequest::IS_ACTIVE, "false");
106     std::string activeUpdateCondition = ReminderRequest::IS_ACTIVE + " is true";
107     std::vector<std::string> activeWhereArgs;
108     int32_t activeResult = rdbStore_->Update(
109         activeChangedRows, REMINDER_DB_TABLE, activeValues, activeUpdateCondition, activeWhereArgs);
110     ANSR_LOGD("Change status isActive to false, changed rows: %{public}d.", activeChangedRows);
111     if (activeResult != NativeRdb::E_OK) {
112         ANSR_LOGE("Init data failed.");
113         return STATE_FAIL;
114     }
115 
116     int32_t scheduledChangedRows = STATE_FAIL;
117     NativeRdb::ValuesBucket scheduledValues;
118     scheduledValues.PutString(ReminderRequest::HAS_SCHEDULED_TIMEOUT, "false");
119     std::string scheduledUpdateCondition = ReminderRequest::HAS_SCHEDULED_TIMEOUT + " is true";
120     std::vector<std::string> scheduledWhereArgs;
121     int32_t scheduledResult = rdbStore_->Update(
122         scheduledChangedRows, REMINDER_DB_TABLE, scheduledValues, scheduledUpdateCondition, scheduledWhereArgs);
123     ANSR_LOGD("Change status has_ScheduledTimeout to false, changed rows: %{public}d.", scheduledChangedRows);
124     if (scheduledResult != NativeRdb::E_OK) {
125         ANSR_LOGE("Init data failed.");
126         return STATE_FAIL;
127     }
128     return ReminderStore::STATE_OK;
129 }
130 
Delete(int32_t reminderId)131 int32_t ReminderStore::Delete(int32_t reminderId)
132 {
133     std::string deleteCondition = ReminderRequest::REMINDER_ID
134         + " = " + std::to_string(reminderId);
135     return ReminderStore::Delete(deleteCondition);
136 }
137 
DeleteUser(int32_t userId)138 int32_t ReminderStore::DeleteUser(int32_t userId)
139 {
140     std::string deleteCondition = ReminderRequest::USER_ID + " = " + std::to_string(userId);
141     return ReminderStore::Delete(deleteCondition);
142 }
143 
Delete(const std::string & pkg,int32_t userId)144 int32_t ReminderStore::Delete(const std::string &pkg, int32_t userId)
145 {
146     std::string deleteCondition = ReminderRequest::PKG_NAME + " = " + pkg + " and "
147         + ReminderRequest::USER_ID + " = " + std::to_string(userId);
148     return ReminderStore::Delete(deleteCondition);
149 }
150 
Delete(const std::string & deleteCondition)151 int32_t ReminderStore::Delete(const std::string &deleteCondition)
152 {
153     if (rdbStore_ == nullptr) {
154         ANSR_LOGE("Rdb store is not initialized.");
155         return STATE_FAIL;
156     }
157     int32_t deletedRows = STATE_FAIL;
158     std::vector<std::string> whereArgs;
159     int32_t result = rdbStore_->Delete(deletedRows, REMINDER_DB_TABLE, deleteCondition, whereArgs);
160     if (result != NativeRdb::E_OK) {
161         ANSR_LOGE("Delete operation failed, deleteConditon: %{public}s," \
162             "result: %{public}d.", deleteCondition.c_str(), result);
163     }
164     ANSR_LOGD("Delete operation done, deleteConditon: %{public}s," \
165         "deleted rows: %{public}d.", deleteCondition.c_str(), deletedRows);
166     return deletedRows;
167 }
168 
UpdateOrInsert(const sptr<ReminderRequest> & reminder,const sptr<NotificationBundleOption> & bundleOption)169 int64_t ReminderStore::UpdateOrInsert(
170     const sptr<ReminderRequest> &reminder, const sptr<NotificationBundleOption> &bundleOption)
171 {
172     if (reminder->GetReminderType() == ReminderRequest::ReminderType::TIMER) {
173         ANSR_LOGI("Countdown not support persist.");
174         return STATE_FAIL;
175     }
176     int64_t isSuccess = STATE_FAIL;
177     if (rdbStore_ == nullptr) {
178         ANSR_LOGE("Rdb store is not initialized.");
179         return isSuccess;
180     }
181     if (bundleOption == nullptr) {
182         ANSR_LOGE("BundleOption is null.");
183         return isSuccess;
184     }
185     if (IsReminderExist(reminder)) {
186         isSuccess = Update(reminder, bundleOption);
187     } else {
188         isSuccess = Insert(reminder, bundleOption);
189     }
190     return isSuccess;
191 }
192 
Insert(const sptr<ReminderRequest> & reminder,const sptr<NotificationBundleOption> & bundleOption)193 int64_t ReminderStore::Insert(
194     const sptr<ReminderRequest> &reminder, const sptr<NotificationBundleOption> &bundleOption)
195 {
196     int64_t rowId = STATE_FAIL;
197     NativeRdb::ValuesBucket values;
198     ReminderStore::GenerateData(reminder, bundleOption, values);
199     int32_t result = rdbStore_->Insert(rowId, REMINDER_DB_TABLE, values);
200     if (result != NativeRdb::E_OK) {
201         ANSR_LOGE("Insert operation failed, result: %{public}d, reminderId=%{public}d.",
202             result, reminder->GetReminderId());
203         return result;
204     }
205     ANSR_LOGD("Insert successfully, reminderId=%{public}d.", reminder->GetReminderId());
206     return result;
207 }
208 
Update(const sptr<ReminderRequest> & reminder,const sptr<NotificationBundleOption> & bundleOption)209 int64_t ReminderStore::Update(
210     const sptr<ReminderRequest> &reminder, const sptr<NotificationBundleOption> &bundleOption)
211 {
212     int32_t changedRows = STATE_FAIL;
213     NativeRdb::ValuesBucket values;
214     ReminderStore::GenerateData(reminder, bundleOption, values);
215     std::string updateCondition = ReminderRequest::REMINDER_ID
216         + " = " + std::to_string(reminder->GetReminderId());
217     std::vector<std::string> whereArgs;
218     int32_t result = rdbStore_->Update(changedRows, REMINDER_DB_TABLE, values, updateCondition, whereArgs);
219     if ((result != NativeRdb::E_OK) || (changedRows <= 0)) {
220         ANSR_LOGE("Update operation failed, result: %{public}d, updated rows: %{public}d, reminderId=%{public}d.",
221             result, changedRows, reminder->GetReminderId());
222         return result;
223     }
224     ANSR_LOGD("Update successfully, updated rows: %{public}d, reminderId=%{public}d.",
225         changedRows, reminder->GetReminderId());
226     return result;
227 }
228 
IsReminderExist(const sptr<ReminderRequest> & reminder)229 bool ReminderStore::IsReminderExist(const sptr<ReminderRequest> &reminder)
230 {
231     std::string queryCondition = "select " + ReminderRequest::REMINDER_ID
232         + " from " + REMINDER_DB_TABLE + " where "
233         + ReminderRequest::REMINDER_ID + " = " + std::to_string(reminder->GetReminderId());
234     std::vector<std::string> whereArgs;
235     std::unique_ptr<NativeRdb::AbsSharedResultSet> queryResultSet = rdbStore_->QuerySql(queryCondition, whereArgs);
236     if (queryResultSet == nullptr) {
237         ANSR_LOGE("QueryResultSet is null.");
238         return false;
239     }
240     int32_t resultNum;
241     queryResultSet->GetRowCount(resultNum);
242     if (resultNum == 0) {
243         return false;
244     }
245     return true;
246 }
247 
Query(const std::string & queryCondition) const248 std::shared_ptr<NativeRdb::AbsSharedResultSet> ReminderStore::Query(const std::string &queryCondition) const
249 {
250     std::unique_ptr<NativeRdb::AbsSharedResultSet> queryResultSet;
251     if (rdbStore_ == nullptr) {
252         ANSR_LOGE("Rdb store is not initialized.");
253         return queryResultSet;
254     }
255     std::vector<std::string> whereArgs;
256     queryResultSet = rdbStore_->QuerySql(queryCondition, whereArgs);
257     return queryResultSet;
258 }
259 
GetColumnIndex(const std::string & name)260 uint8_t ReminderStore::GetColumnIndex(const std::string& name)
261 {
262     uint8_t index = 0;
263     for (auto it = columns.begin(); it != columns.end(); ++it) {
264         if (name == (*it)) {
265             break;
266         }
267         index++;
268     }
269     return index;
270 }
271 
GetMaxId()272 int32_t ReminderStore::GetMaxId()
273 {
274     if (rdbStore_ == nullptr) {
275         ANSR_LOGE("Rdb store is not initialized.");
276         return STATE_FAIL;
277     }
278     std::string queryCondition = "select " + ReminderRequest::REMINDER_ID
279         + " from " + REMINDER_DB_TABLE + " order by "
280         + ReminderRequest::REMINDER_ID + " desc";
281     std::shared_ptr<NativeRdb::AbsSharedResultSet> queryResultSet = ReminderStore::Query(queryCondition);
282     if (queryResultSet == nullptr) {
283         ANSR_LOGE("QueryResultSet is null.");
284         return STATE_FAIL;
285     }
286     int32_t resultNum;
287     queryResultSet->GetRowCount(resultNum);
288     if (resultNum == 0) {
289         ANSR_LOGI("QueryResultSet is zero.");
290         return STATE_FAIL;
291     }
292     queryResultSet->GoToNextRow();
293     int32_t maxId = STATE_FAIL;
294     int32_t result = queryResultSet->GetInt(0, maxId);
295     if (result != NativeRdb::E_OK) {
296         ANSR_LOGE("Query operation failed, result %{public}d.", result);
297     }
298     ANSR_LOGD("MaxId: %{public}d.", maxId);
299     return maxId;
300 }
301 
GetAllValidReminders()302 std::vector<sptr<ReminderRequest>> ReminderStore::GetAllValidReminders()
303 {
304     std::string queryCondition = "select * from " + REMINDER_DB_TABLE + " where "
305         + ReminderRequest::IS_EXPIRED + " is false order by "
306         + ReminderRequest::TRIGGER_TIME + " asc";
307     ANSR_LOGD("Get all reminders");
308     return GetReminders(queryCondition);
309 }
310 
GetReminders(const std::string & queryCondition)311 std::vector<sptr<ReminderRequest>> ReminderStore::GetReminders(const std::string &queryCondition)
312 {
313     std::vector<sptr<ReminderRequest>> reminders;
314     if (rdbStore_ == nullptr) {
315         ANSR_LOGE("Rdb store is not initialized.");
316         return reminders;
317     }
318     std::shared_ptr<NativeRdb::AbsSharedResultSet> queryResultSet = Query(queryCondition);
319     if (queryResultSet == nullptr) {
320         return reminders;
321     }
322     bool isAtLastRow = false;
323     queryResultSet->IsAtLastRow(isAtLastRow);
324     while (!isAtLastRow) {
325         queryResultSet->GoToNextRow();
326         sptr<ReminderRequest> reminder;
327         reminder = BuildReminder(queryResultSet);
328         reminders.push_back(reminder);
329         queryResultSet->IsAtLastRow(isAtLastRow);
330     }
331     ANSR_LOGD("Size=%{public}d", reminders.size());
332     return reminders;
333 }
334 
BuildReminder(const std::shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet)335 sptr<ReminderRequest> ReminderStore::BuildReminder(const std::shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet)
336 {
337     int32_t reminderType;
338     int32_t reminderId;
339     resultSet->GetInt(ReminderStore::GetColumnIndex(ReminderRequest::REMINDER_TYPE), reminderType);
340     resultSet->GetInt(ReminderStore::GetColumnIndex(ReminderRequest::REMINDER_ID), reminderId);
341 
342     sptr<ReminderRequest> reminder = nullptr;
343     switch (reminderType) {
344         case (static_cast<int32_t>(ReminderRequest::ReminderType::TIMER)): {
345             reminder = new (std::nothrow) ReminderRequestTimer(reminderId);
346             break;
347         }
348         case (static_cast<int32_t>(ReminderRequest::ReminderType::CALENDAR)): {
349             reminder = new (std::nothrow) ReminderRequestCalendar(reminderId);
350             break;
351         }
352         case (static_cast<int32_t>(ReminderRequest::ReminderType::ALARM)): {
353             reminder = new (std::nothrow) ReminderRequestAlarm(reminderId);
354             break;
355         }
356         default: {
357             ANSR_LOGE("ReminderType from database is error, reminderType %{public}d.", reminderType);
358             break;
359         }
360     }
361     if (reminder != nullptr) {
362         reminder->RecoverFromDb(resultSet);
363         ANSR_LOGI("BuildReminder success.");
364     } else {
365         ANSR_LOGW("BuildReminder fail.");
366     }
367     return reminder;
368 }
369 
GetBundleOption(const int32_t & reminderId,sptr<NotificationBundleOption> & bundleOption) const370 bool ReminderStore::GetBundleOption(const int32_t &reminderId, sptr<NotificationBundleOption> &bundleOption) const
371 {
372     std::string queryCondition = "select " + ReminderRequest::PKG_NAME + ", "
373         + ReminderRequest::UID + " from " + REMINDER_DB_TABLE + " where "
374         + ReminderRequest::REMINDER_ID + "=" + std::to_string(reminderId);
375     std::shared_ptr<NativeRdb::AbsSharedResultSet> queryResultSet = Query(queryCondition);
376     if (queryResultSet == nullptr) {
377         return false;
378     }
379     bool isAtLastRow = false;
380     queryResultSet->IsAtLastRow(isAtLastRow);
381     if (isAtLastRow) {
382         return false;
383     }
384     queryResultSet->GoToNextRow();
385     std::string pkgName;
386     GetStringVal(queryResultSet, ReminderRequest::PKG_NAME, pkgName);
387     int32_t uid;
388     GetInt32Val(queryResultSet, ReminderRequest::UID, uid);
389     bundleOption->SetBundleName(pkgName);
390     bundleOption->SetUid(uid);
391     return true;
392 }
393 
GetInt32Val(std::shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet,const std::string & name,int32_t & value) const394 void ReminderStore::GetInt32Val(std::shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet,
395     const std::string &name, int32_t &value) const
396 {
397     int32_t columnIndex;
398     resultSet->GetColumnIndex(name, columnIndex);
399     resultSet->GetInt(columnIndex, value);
400 }
401 
GetStringVal(std::shared_ptr<NativeRdb::AbsSharedResultSet> & resultSet,const std::string & name,std::string & value) const402 void ReminderStore::GetStringVal(std::shared_ptr<NativeRdb::AbsSharedResultSet> &resultSet,
403     const std::string &name, std::string &value) const
404 {
405     int32_t columnIndex;
406     resultSet->GetColumnIndex(name, columnIndex);
407     resultSet->GetString(columnIndex, value);
408 }
409 
GenerateData(const sptr<ReminderRequest> & reminder,const sptr<NotificationBundleOption> & bundleOption,NativeRdb::ValuesBucket & values) const410 void ReminderStore::GenerateData(const sptr<ReminderRequest> &reminder,
411     const sptr<NotificationBundleOption> &bundleOption, NativeRdb::ValuesBucket &values) const
412 {
413     ReminderRequest::AppendValuesBucket(reminder, bundleOption, values);
414     ReminderRequestCalendar::AppendValuesBucket(reminder, bundleOption, values);
415     ReminderRequestAlarm::AppendValuesBucket(reminder, bundleOption, values);
416 }
417 }  // namespace Notification
418 }  // namespace OHOS
419