• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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