• 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 #include "bundle_active_core.h"
16 #include "app_group_callback_info.h"
17 #include "bundle_active_user_history.h"
18 
19 namespace OHOS {
20 namespace DeviceUsageStats {
21 using namespace DeviceUsageStatsGroupConst;
22 using namespace std;
23 
BundleActivePackageHistory()24 BundleActivePackageHistory::BundleActivePackageHistory()
25 {
26     lastBootFromUsedTimeStamp_ = 0;
27     lastScreenUsedTimeStamp_ = 0;
28     lastGroupCalculatedTimeStamp_ = 0;
29     currentGroup_ = DeviceUsageStatsGroupConst::ACTIVE_GROUP_NEVER;
30     reasonInGroup_ = DeviceUsageStatsGroupConst::GROUP_CONTROL_REASON_DEFAULT;
31     bundleAliveTimeoutTimeStamp_ = 0;
32     bundleDailyTimeoutTimeStamp_ = 0;
33     lastCalculatedGroup_ = ACTIVE_GROUP_NEVER;
34     isChanged_ = false;
35 };
36 
WriteDeviceDuration()37 void BundleActiveUserHistory::WriteDeviceDuration()
38 {
39     database_.PutDurationData(bootBasedDuration_, ScreenOnDuration_);
40 }
41 
WriteBundleUsage(const int32_t userId)42 void BundleActiveUserHistory::WriteBundleUsage(const int32_t userId)
43 {
44     BUNDLE_ACTIVE_LOGI("WriteBundleUsage called");
45     auto userHistory = GetUserHistory(userId, false);
46     if (userHistory == nullptr) {
47         BUNDLE_ACTIVE_LOGI("WriteBundleUsage called, no existed user history, return");
48         return;
49     }
50     database_.PutBundleHistoryData(userId, userHistory);
51 }
52 
OnBundleUninstalled(const int32_t userId,const std::string bundleName)53 void BundleActiveUserHistory::OnBundleUninstalled(const int32_t userId, const std::string bundleName)
54 {
55     database_.OnPackageUninstalled(userId, bundleName);
56 }
57 
BundleActiveUserHistory(const int64_t bootBasedTimeStamp,const std::shared_ptr<BundleActiveCore> & bundleActiveCore)58 BundleActiveUserHistory::BundleActiveUserHistory(const int64_t bootBasedTimeStamp,
59     const std::shared_ptr<BundleActiveCore>& bundleActiveCore)
60 {
61     bootBasedTimeStamp_ = bootBasedTimeStamp;
62     screenOnTimeStamp_ = bootBasedTimeStamp;
63     database_.InitUsageGroupDatabase(APP_GROUP_DATABASE_INDEX, false);
64     auto bootAndScreenOnDuraton = database_.GetDurationData();
65     bootBasedDuration_ = bootAndScreenOnDuraton.first;
66     ScreenOnDuration_ = bootAndScreenOnDuraton.second;
67     isScreenOn_ = false;
68     if (bundleActiveCore) {
69         bundleActiveCore_ = bundleActiveCore;
70     }
71 }
72 
GetLevelIndex(const string & bundleName,const int32_t userId,const int64_t bootBasedTimeStamp,const std::vector<int64_t> screenTimeLevel,const std::vector<int64_t> bootFromTimeLevel)73 int32_t BundleActiveUserHistory::GetLevelIndex(const string& bundleName, const int32_t userId,
74     const int64_t bootBasedTimeStamp, const std::vector<int64_t> screenTimeLevel,
75     const std::vector<int64_t> bootFromTimeLevel)
76 {
77     auto oneUserHistory = GetUserHistory(userId, false);
78     if (oneUserHistory == nullptr) {
79         return -1;
80     }
81     auto oneBundleHistory = GetUsageHistoryInUserHistory(oneUserHistory, bundleName, bootBasedTimeStamp, false);
82     if (oneBundleHistory == nullptr) {
83         return -1;
84     }
85     int64_t screenDiff = GetScreenOnTimeStamp(bootBasedTimeStamp) - oneBundleHistory->lastScreenUsedTimeStamp_;
86     int64_t bootFromDiff = GetBootBasedTimeStamp(bootBasedTimeStamp) - oneBundleHistory->lastBootFromUsedTimeStamp_;
87     BUNDLE_ACTIVE_LOGI("screendiff is %{public}lld, bootfromdiff is %{public}lld, bundle name is %{public}s,"
88         "userid is %{public}d",
89         (long long)screenDiff, (long long)bootFromDiff, bundleName.c_str(), userId);
90     for (int32_t i = 3; i >= 0; i--) {
91         if (screenDiff >= screenTimeLevel[i] && bootFromDiff >= bootFromTimeLevel[i]) {
92             return i;
93         }
94     }
95     return -1;
96 }
97 
GetBootBasedTimeStamp(int64_t bootBasedTimeStamp)98 int64_t BundleActiveUserHistory::GetBootBasedTimeStamp(int64_t bootBasedTimeStamp)
99 {
100     return bootBasedTimeStamp - bootBasedTimeStamp_ + bootBasedDuration_;
101 }
102 
GetScreenOnTimeStamp(int64_t bootBasedTimeStamp)103 int64_t BundleActiveUserHistory::GetScreenOnTimeStamp(int64_t bootBasedTimeStamp)
104 {
105     int64_t result = ScreenOnDuration_;
106     if (isScreenOn_) {
107         result += bootBasedTimeStamp - screenOnTimeStamp_;
108     }
109     return result;
110 }
111 
GetUserHistory(const int32_t userId,const bool create)112 shared_ptr<map<string, shared_ptr<BundleActivePackageHistory>>> BundleActiveUserHistory::GetUserHistory(
113     const int32_t userId, const bool create)
114 {
115     auto it = userHistory_.find(userId);
116     if ((it == userHistory_.end()) && create) {
117         shared_ptr<map<string, shared_ptr<BundleActivePackageHistory>>> usageHistoryInserted =
118             database_.GetBundleHistoryData(userId);
119         if (!usageHistoryInserted) {
120             BUNDLE_ACTIVE_LOGI("GetUserHistory READ FROM DATABASE FAILD");
121             usageHistoryInserted =
122                 make_shared<map<string, shared_ptr<BundleActivePackageHistory>>>();
123         }
124         BUNDLE_ACTIVE_LOGI("GetUserHistory usageHistoryInserted not null");
125         userHistory_[userId] = usageHistoryInserted;
126     }
127     return userHistory_[userId];
128 }
129 
GetUsageHistoryInUserHistory(shared_ptr<map<string,shared_ptr<BundleActivePackageHistory>>> oneUserHistory,string bundleName,int64_t bootBasedTimeStamp,const bool create)130 shared_ptr<BundleActivePackageHistory> BundleActiveUserHistory::GetUsageHistoryInUserHistory(
131     shared_ptr<map<string, shared_ptr<BundleActivePackageHistory>>> oneUserHistory,
132     string bundleName, int64_t bootBasedTimeStamp, const bool create)
133 {
134     if (!oneUserHistory) {
135         return nullptr;
136     }
137     auto it = oneUserHistory->find(bundleName);
138     if ((it == oneUserHistory->end()) && create) {
139         shared_ptr<BundleActivePackageHistory> usageHistoryInserted =
140             make_shared<BundleActivePackageHistory>();
141         usageHistoryInserted->lastBootFromUsedTimeStamp_ = GetBootBasedTimeStamp(bootBasedTimeStamp);
142         usageHistoryInserted->lastScreenUsedTimeStamp_ = GetScreenOnTimeStamp(bootBasedTimeStamp);
143         usageHistoryInserted->currentGroup_ = ACTIVE_GROUP_NEVER;
144         usageHistoryInserted->reasonInGroup_ = GROUP_CONTROL_REASON_DEFAULT;
145         usageHistoryInserted->bundleAliveTimeoutTimeStamp_ = 0;
146         usageHistoryInserted->bundleDailyTimeoutTimeStamp_ = 0;
147         (*oneUserHistory)[bundleName] = usageHistoryInserted;
148     }
149     return (*oneUserHistory)[bundleName];
150 }
151 
GetUsageHistoryForBundle(const string & bundleName,const int32_t userId,const int64_t bootBasedTimeStamp,const bool create)152 shared_ptr<BundleActivePackageHistory> BundleActiveUserHistory::GetUsageHistoryForBundle(
153     const string& bundleName, const int32_t userId, const int64_t bootBasedTimeStamp, const bool create)
154 {
155     auto oneUserHistory = GetUserHistory(userId, create);
156     if (!oneUserHistory) {
157         return nullptr;
158     }
159     auto oneBundleHistory = GetUsageHistoryInUserHistory(oneUserHistory, bundleName, bootBasedTimeStamp, create);
160     if (!oneBundleHistory) {
161         return nullptr;
162     }
163     return oneBundleHistory;
164 }
165 
ReportUsage(shared_ptr<BundleActivePackageHistory> oneBundleUsageHistory,const string & bundleName,const int32_t newGroup,const uint32_t groupReason,const int64_t bootBasedTimeStamp,const int64_t timeUntilNextCheck,const int32_t userId)166 void BundleActiveUserHistory::ReportUsage(shared_ptr<BundleActivePackageHistory> oneBundleUsageHistory,
167     const string& bundleName, const int32_t newGroup, const uint32_t groupReason, const int64_t bootBasedTimeStamp,
168     const int64_t timeUntilNextCheck, const int32_t userId)
169 {
170     if ((oneBundleUsageHistory->reasonInGroup_ & GROUP_CONTROL_REASON_MASK) == GROUP_CONTROL_REASON_FORCED) {
171         return;
172     }
173     if (timeUntilNextCheck > bootBasedTimeStamp) {
174         int64_t nextCheckTimeStamp = bootBasedDuration_ + (timeUntilNextCheck - bootBasedTimeStamp_);
175         if (newGroup == ACTIVE_GROUP_ALIVE) {
176             oneBundleUsageHistory->bundleAliveTimeoutTimeStamp_ = max(nextCheckTimeStamp,
177                 oneBundleUsageHistory->bundleAliveTimeoutTimeStamp_);
178         } else if (newGroup == ACTIVE_GROUP_DAILY) {
179             oneBundleUsageHistory->bundleDailyTimeoutTimeStamp_ = max(nextCheckTimeStamp,
180                 oneBundleUsageHistory->bundleDailyTimeoutTimeStamp_);
181         } else {
182             return;
183         }
184     }
185     if (bootBasedTimeStamp > 0) {
186         oneBundleUsageHistory->lastBootFromUsedTimeStamp_ = bootBasedDuration_ +
187             (bootBasedTimeStamp - bootBasedTimeStamp_);
188         oneBundleUsageHistory->lastScreenUsedTimeStamp_ = GetScreenOnTimeStamp(bootBasedTimeStamp);
189     }
190     int32_t oldGroup = oneBundleUsageHistory->currentGroup_;
191     if (oneBundleUsageHistory->currentGroup_ > newGroup) {
192         oneBundleUsageHistory->currentGroup_ = newGroup;
193     }
194     oneBundleUsageHistory->reasonInGroup_ = GROUP_CONTROL_REASON_USAGE | groupReason;
195     oneBundleUsageHistory->isChanged_ = true;
196     BUNDLE_ACTIVE_LOGI("RegisterAppGroupCallBack will ReportUsage");
197     bool isGroupChanged = (oldGroup == newGroup) ? true : false;
198     if (!isGroupChanged) {
199         AppGroupCallbackInfo callbackInfo(
200             userId, oldGroup, newGroup, oneBundleUsageHistory->reasonInGroup_, bundleName);
201         BUNDLE_ACTIVE_LOGI("RegisterAppGroupCallBack AppGroupCallbackInfo build success");
202         if (!bundleActiveCore_.expired()) {
203             BUNDLE_ACTIVE_LOGI("RegisterAppGroupCallBack will callback!");
204             bundleActiveCore_.lock()->OnAppGroupChanged(callbackInfo);
205         }
206     }
207 }
208 
SetAppGroup(const string & bundleName,const int32_t userId,const int64_t bootBasedTimeStamp,int32_t newGroup,uint32_t groupReason,const bool isFlush)209 int32_t BundleActiveUserHistory::SetAppGroup(const string& bundleName, const int32_t userId,
210     const int64_t bootBasedTimeStamp, int32_t newGroup, uint32_t groupReason, const bool isFlush)
211 {
212     std::lock_guard<std::mutex> lock(setGroupMutex_);
213     BUNDLE_ACTIVE_LOGI("set %{public}s to group %{public}d, reason is %{public}d, userId is %{public}d",
214         bundleName.c_str(), newGroup, groupReason, userId);
215     shared_ptr<map<string, shared_ptr<BundleActivePackageHistory>>> userBundleHistory = GetUserHistory(userId, false);
216     if (!userBundleHistory) {
217         return ERR_GET_BUNDLE_USED_HISTORY_FAILED;
218     }
219     shared_ptr<BundleActivePackageHistory> oneBundleHistory = GetUsageHistoryInUserHistory(userBundleHistory,
220         bundleName, bootBasedTimeStamp, false);
221     if (!oneBundleHistory) {
222         return ERR_GET_BUNDLE_USED_HISTORY_FAILED;
223     }
224     if (oneBundleHistory->currentGroup_ == newGroup && oneBundleHistory->reasonInGroup_ == groupReason) {
225         BUNDLE_ACTIVE_LOGI("%{public}s group and reason is same as before, not update", bundleName.c_str());
226         return ERR_REPEAT_SET_APP_GROUP;
227     }
228     int32_t oldGroup = oneBundleHistory->currentGroup_;
229     oneBundleHistory->currentGroup_ = newGroup;
230     oneBundleHistory->reasonInGroup_ = groupReason;
231     oneBundleHistory->isChanged_ = true;
232     BUNDLE_ACTIVE_LOGI("SetAppGroup set success");
233     if (isFlush) {
234         WriteBundleUsage(userId);
235     }
236 
237     bool isGroupChanged = (oldGroup == newGroup) ? true : false;
238     if (!isGroupChanged) {
239         AppGroupCallbackInfo callbackInfo(
240             userId, oldGroup, newGroup, oneBundleHistory->reasonInGroup_, bundleName);
241         if (!bundleActiveCore_.expired()) {
242             bundleActiveCore_.lock()->OnAppGroupChanged(callbackInfo);
243         }
244     }
245     return ERR_OK;
246 }
247 
UpdateBootBasedAndScreenTime(const bool & isScreenOn,const int64_t bootBasedTimeStamp,const bool & isShutdown)248 void BundleActiveUserHistory::UpdateBootBasedAndScreenTime(const bool& isScreenOn, const int64_t bootBasedTimeStamp,
249     const bool& isShutdown)
250 {
251     if (isScreenOn_ == isScreenOn && isShutdown == false) {
252         return;
253     }
254     isScreenOn_ = isScreenOn;
255     if (isScreenOn_) {
256         screenOnTimeStamp_ = bootBasedTimeStamp;
257     } else {
258         ScreenOnDuration_ += bootBasedTimeStamp - screenOnTimeStamp_;
259         bootBasedDuration_ += bootBasedTimeStamp - bootBasedTimeStamp_;
260         bootBasedTimeStamp_ = bootBasedTimeStamp;
261     }
262     database_.PutDurationData(bootBasedDuration_, ScreenOnDuration_);
263 }
264 
PrintData(int32_t userId)265 void BundleActiveUserHistory::PrintData(int32_t userId)
266 {
267     auto oneUserHistory = GetUserHistory(userId, false);
268     BUNDLE_ACTIVE_LOGI("PrintData screen is %{public}d", isScreenOn_);
269     if (oneUserHistory == nullptr) {
270         return;
271     }
272     for (auto oneBundleUsage : (*oneUserHistory)) {
273         BUNDLE_ACTIVE_LOGI("bundle name is %{public}s, lastBootFromUsedTimeStamp_ is %{public}lld, "
274             "lastScreenUsedTimeStamp_ is %{public}lld, currentGroup_ is %{public}d, reasonInGroup_ is %{public}d, "
275             "daily time out %{public}lld, alive time out %{public}lld", oneBundleUsage.first.c_str(),
276             (long long)oneBundleUsage.second->lastBootFromUsedTimeStamp_,
277             (long long)oneBundleUsage.second->lastScreenUsedTimeStamp_,
278             oneBundleUsage.second->currentGroup_, oneBundleUsage.second->reasonInGroup_,
279             (long long)oneBundleUsage.second->bundleDailyTimeoutTimeStamp_,
280             (long long)oneBundleUsage.second->bundleAliveTimeoutTimeStamp_);
281     }
282 }
283 }  // namespace DeviceUsageStats
284 }  // namespace OHOS
285 
286