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 "medialibrary_appstate_observer.h"
16
17 #include <cstddef>
18 #include <sstream>
19 #include <string>
20
21 #include "if_system_ability_manager.h"
22 #include "iservice_registry.h"
23 #include "media_app_uri_permission_column.h"
24 #include "media_app_uri_sensitive_column.h"
25 #include "media_library_manager.h"
26 #include "media_log.h"
27 #include "medialibrary_data_manager.h"
28 #include "medialibrary_errno.h"
29 #include "permission_utils.h"
30 #include "system_ability_definition.h"
31
32 namespace OHOS {
33 namespace Media {
34 using namespace OHOS::AppExecFwk;
35
GetAppManagerInstance()36 sptr<IAppMgr> MedialibraryAppStateObserverManager::GetAppManagerInstance()
37 {
38 sptr<ISystemAbilityManager> systemAbilityManager =
39 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
40 if (systemAbilityManager == nullptr) {
41 MEDIA_ERR_LOG("systemAbilityManager is nullptr");
42 return nullptr;
43 }
44
45 sptr<IRemoteObject> object = systemAbilityManager->GetSystemAbility(APP_MGR_SERVICE_ID);
46 if (object == nullptr) {
47 MEDIA_ERR_LOG("systemAbilityManager remote object is nullptr");
48 return nullptr;
49 }
50
51 return iface_cast<IAppMgr>(object);
52 }
53
SubscribeAppState()54 void MedialibraryAppStateObserverManager::SubscribeAppState()
55 {
56 MEDIA_INFO_LOG("SubscribeAppState");
57 sptr<IAppMgr> appManager = GetAppManagerInstance();
58 if (appManager == nullptr) {
59 MEDIA_ERR_LOG("GetAppManagerInstance failed");
60 return;
61 }
62
63 if (appStateObserver_ != nullptr) {
64 MEDIA_INFO_LOG("appStateObserver has been registed");
65 return;
66 }
67
68 appStateObserver_ = new (std::nothrow) MedialibraryAppStateObserver();
69 if (appStateObserver_ == nullptr) {
70 MEDIA_ERR_LOG("get appStateObserver failed");
71 return;
72 }
73
74 int32_t result = appManager->RegisterApplicationStateObserver(appStateObserver_);
75 if (result != E_SUCCESS) {
76 MEDIA_ERR_LOG("RegistApplicationStateObserver failed");
77 appStateObserver_ = nullptr;
78 return;
79 }
80
81 MEDIA_INFO_LOG("SubscribeAppState success");
82 return;
83 }
84
UnSubscribeAppState()85 void MedialibraryAppStateObserverManager::UnSubscribeAppState()
86 {
87 if (appStateObserver_ == nullptr) {
88 MEDIA_ERR_LOG("appStateObserver_ is nullptr");
89 return;
90 }
91
92 sptr<IAppMgr> appManager = GetAppManagerInstance();
93 if (appManager == nullptr) {
94 MEDIA_ERR_LOG("GetAppManagerInstance failed");
95 return;
96 }
97
98 int32_t result = appManager->UnregisterApplicationStateObserver(appStateObserver_);
99 if (result != E_SUCCESS) {
100 MEDIA_ERR_LOG("UnregisterApplicationStateObserver failed");
101 return;
102 }
103
104 appStateObserver_ = nullptr;
105 MEDIA_INFO_LOG("UnSubscribeAppState success");
106 return;
107 }
108
GetInstance()109 MedialibraryAppStateObserverManager &MedialibraryAppStateObserverManager::GetInstance()
110 {
111 static MedialibraryAppStateObserverManager instance;
112 return instance;
113 }
114
CountTemporaryPermission(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)115 static int32_t CountTemporaryPermission(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
116 {
117 NativeRdb::AbsRdbPredicates predicatesUnSubscribe(AppUriPermissionColumn::APP_URI_PERMISSION_TABLE);
118 vector<string> permissionTypes;
119 permissionTypes.emplace_back(to_string(
120 static_cast<int32_t>(PhotoPermissionType::TEMPORARY_READ_IMAGEVIDEO)));
121 permissionTypes.emplace_back(to_string(
122 static_cast<int32_t>(PhotoPermissionType::TEMPORARY_WRITE_IMAGEVIDEO)));
123 permissionTypes.emplace_back(to_string(
124 static_cast<int32_t>(PhotoPermissionType::TEMPORARY_READWRITE_IMAGEVIDEO)));
125 predicatesUnSubscribe.And()->In(AppUriPermissionColumn::PERMISSION_TYPE, permissionTypes);
126 vector<string> columns = { AppUriPermissionColumn::ID };
127 auto resultSet = rdbStore->Query(predicatesUnSubscribe, columns);
128 if (resultSet == nullptr) {
129 MEDIA_ERR_LOG("Can not query URIPERMISSION");
130 return E_ERR;
131 }
132
133 int32_t count = 0;
134 auto ret = resultSet->GetRowCount(count);
135 if (ret != NativeRdb::E_OK) {
136 MEDIA_ERR_LOG("GetRowCount failed ret:%{public}d", ret);
137 return E_ERR;
138 }
139
140 return count;
141 }
142
CountHideSensitive(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)143 static int32_t CountHideSensitive(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
144 {
145 NativeRdb::AbsRdbPredicates predicatesUnSubscribe(AppUriSensitiveColumn::APP_URI_SENSITIVE_TABLE);
146 vector<string> columns = { AppUriPermissionColumn::ID };
147 auto resultSet = rdbStore->Query(predicatesUnSubscribe, columns);
148 if (resultSet == nullptr) {
149 MEDIA_ERR_LOG("Can not query URIPERMISSION");
150 return E_ERR;
151 }
152
153 int32_t count = 0;
154 auto ret = resultSet->GetRowCount(count);
155 if (ret != NativeRdb::E_OK) {
156 MEDIA_ERR_LOG("GetRowCount failed ret:%{public}d", ret);
157 return E_ERR;
158 }
159
160 return count;
161 }
162
TryUnSubscribeAppState(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)163 static void TryUnSubscribeAppState(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
164 {
165 int32_t countPermission = CountTemporaryPermission(rdbStore);
166 int32_t countSensitive = CountHideSensitive(rdbStore);
167 if (countPermission < 0 || countSensitive < 0) {
168 MEDIA_ERR_LOG("TryUnSubscribeAppState System exception");
169 }
170 if (countPermission == 0 && countSensitive == 0) {
171 MedialibraryAppStateObserverManager::GetInstance().UnSubscribeAppState();
172 MEDIA_INFO_LOG("No temporary permission record remains ,UnSubscribeAppState");
173 }
174 }
175
DeleteTemporaryPermission(const std::shared_ptr<MediaLibraryRdbStore> rdbStore,const string & appId)176 static int32_t DeleteTemporaryPermission(const std::shared_ptr<MediaLibraryRdbStore> rdbStore, const string &appId)
177 {
178 NativeRdb::AbsRdbPredicates predicates(AppUriPermissionColumn::APP_URI_PERMISSION_TABLE);
179 predicates.EqualTo(AppUriPermissionColumn::APP_ID, appId);
180 vector<string> permissionTypes;
181 permissionTypes.emplace_back(to_string(
182 static_cast<int32_t>(PhotoPermissionType::TEMPORARY_READ_IMAGEVIDEO)));
183 permissionTypes.emplace_back(to_string(
184 static_cast<int32_t>(PhotoPermissionType::TEMPORARY_WRITE_IMAGEVIDEO)));
185 permissionTypes.emplace_back(to_string(
186 static_cast<int32_t>(PhotoPermissionType::TEMPORARY_READWRITE_IMAGEVIDEO)));
187 predicates.And()->In(AppUriPermissionColumn::PERMISSION_TYPE, permissionTypes);
188 int32_t deletedRows = -1;
189 auto ret = rdbStore->Delete(deletedRows, predicates);
190 if (ret != NativeRdb::E_OK || deletedRows < 0) {
191 MEDIA_ERR_LOG("Story Delete db failed, errCode = %{public}d", ret);
192 }
193 MEDIA_INFO_LOG("Uripermission Delete retVal: %{public}d, deletedRows: %{public}d", ret, deletedRows);
194
195 return deletedRows;
196 }
197
DeleteHideSensitive(const std::shared_ptr<MediaLibraryRdbStore> rdbStore,const string & appId)198 static int32_t DeleteHideSensitive(const std::shared_ptr<MediaLibraryRdbStore> rdbStore, const string &appId)
199 {
200 NativeRdb::AbsRdbPredicates predicates(AppUriSensitiveColumn::APP_URI_SENSITIVE_TABLE);
201 predicates.EqualTo(AppUriPermissionColumn::APP_ID, appId);
202 int32_t deletedRows = -1;
203 auto ret = rdbStore->Delete(deletedRows, predicates);
204 if (ret != NativeRdb::E_OK || deletedRows < 0) {
205 MEDIA_ERR_LOG("Story Delete db failed, errCode = %{public}d", ret);
206 }
207 MEDIA_INFO_LOG("Uripermission Delete retVal: %{public}d, deletedRows: %{public}d", ret, deletedRows);
208
209 return deletedRows;
210 }
211
OnAppStopped(const AppStateData & appStateData)212 void MedialibraryAppStateObserver::OnAppStopped(const AppStateData &appStateData)
213 {
214 auto bundleName = appStateData.bundleName;
215 auto uid = appStateData.uid;
216 MEDIA_INFO_LOG("MedialibraryAppStateObserver OnAppStopped, bundleName:%{public}s", bundleName.c_str());
217
218 auto rdbStore = MediaLibraryDataManager::GetInstance()->rdbStore_;
219 if (rdbStore == nullptr) {
220 MEDIA_ERR_LOG("Uripermission Delete failed, rdbStore is null.");
221 return;
222 }
223 string appId = PermissionUtils::GetAppIdByBundleName(bundleName, uid);
224 int32_t deletedRowsPermission = DeleteTemporaryPermission(rdbStore, appId);
225 int32_t deletedRowsSensitive = DeleteHideSensitive(rdbStore, appId);
226 if (deletedRowsPermission == 0 && deletedRowsSensitive == 0) {
227 return;
228 }
229 TryUnSubscribeAppState(rdbStore);
230 }
231 } // namespace Media
232 } // namespace OHOS
233