• 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 constexpr int32_t WAITFOR_REVOKE = 2000;
36 
GetAppManagerInstance()37 sptr<IAppMgr> MedialibraryAppStateObserverManager::GetAppManagerInstance()
38 {
39     sptr<ISystemAbilityManager> systemAbilityManager =
40         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
41     CHECK_AND_RETURN_RET_LOG(systemAbilityManager != nullptr, nullptr, "systemAbilityManager is nullptr");
42 
43     sptr<IRemoteObject> object = systemAbilityManager->GetSystemAbility(APP_MGR_SERVICE_ID);
44     CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "systemAbilityManager remote object is nullptr");
45     return iface_cast<IAppMgr>(object);
46 }
47 
SubscribeAppState()48 void MedialibraryAppStateObserverManager::SubscribeAppState()
49 {
50     MEDIA_INFO_LOG("SubscribeAppState");
51     sptr<IAppMgr> appManager = GetAppManagerInstance();
52     CHECK_AND_RETURN_LOG(appManager != nullptr, "GetAppManagerInstance failed");
53     CHECK_AND_RETURN_INFO_LOG(appStateObserver_ == nullptr, "appStateObserver has been registed");
54 
55     appStateObserver_ = new (std::nothrow) MedialibraryAppStateObserver();
56     CHECK_AND_RETURN_LOG(appStateObserver_ != nullptr, "get appStateObserver failed");
57 
58     int32_t result = appManager->RegisterApplicationStateObserver(appStateObserver_);
59     if (result != E_SUCCESS) {
60         MEDIA_ERR_LOG("RegistApplicationStateObserver failed");
61         appStateObserver_ = nullptr;
62         return;
63     }
64 
65     MEDIA_INFO_LOG("SubscribeAppState success");
66     return;
67 }
68 
UnSubscribeAppState()69 void MedialibraryAppStateObserverManager::UnSubscribeAppState()
70 {
71     CHECK_AND_RETURN_LOG(appStateObserver_ != nullptr, "appStateObserver_ is nullptr");
72 
73     sptr<IAppMgr> appManager = GetAppManagerInstance();
74     CHECK_AND_RETURN_LOG(appManager != nullptr, "GetAppManagerInstance failed");
75 
76     int32_t result = appManager->UnregisterApplicationStateObserver(appStateObserver_);
77     CHECK_AND_RETURN_LOG(result == E_SUCCESS, "UnregisterApplicationStateObserver failed");
78 
79     appStateObserver_ = nullptr;
80     MEDIA_INFO_LOG("UnSubscribeAppState success");
81     return;
82 }
83 
AddTokenId(int64_t tokenId,bool needRevoke)84 void MedialibraryAppStateObserverManager::AddTokenId(int64_t tokenId, bool needRevoke)
85 {
86     revokeMap_.EnsureInsert(tokenId, needRevoke);
87 }
88 
RemoveTokenId(int64_t tokenId)89 void MedialibraryAppStateObserverManager::RemoveTokenId(int64_t tokenId)
90 {
91     revokeMap_.Erase(tokenId);
92 }
93 
NeedRevoke(int64_t tokenId)94 bool MedialibraryAppStateObserverManager::NeedRevoke(int64_t tokenId)
95 {
96     bool needRevoke = true;
97     revokeMap_.Find(tokenId, needRevoke);
98     return needRevoke;
99 }
100 
IsContainTokenId(int64_t tokenId)101 bool MedialibraryAppStateObserverManager::IsContainTokenId(int64_t tokenId)
102 {
103     bool needRevoke = true;
104     return revokeMap_.Find(tokenId, needRevoke);
105 }
106 
GetInstance()107 MedialibraryAppStateObserverManager &MedialibraryAppStateObserverManager::GetInstance()
108 {
109     static MedialibraryAppStateObserverManager instance;
110     return instance;
111 }
112 
CountTemporaryPermission(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)113 static int32_t CountTemporaryPermission(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
114 {
115     NativeRdb::AbsRdbPredicates predicatesUnSubscribe(AppUriPermissionColumn::APP_URI_PERMISSION_TABLE);
116     vector<string> permissionTypes;
117     permissionTypes.emplace_back(to_string(
118         static_cast<int32_t>(PhotoPermissionType::TEMPORARY_READ_IMAGEVIDEO)));
119     permissionTypes.emplace_back(to_string(
120         static_cast<int32_t>(PhotoPermissionType::TEMPORARY_WRITE_IMAGEVIDEO)));
121     permissionTypes.emplace_back(to_string(
122         static_cast<int32_t>(PhotoPermissionType::TEMPORARY_READWRITE_IMAGEVIDEO)));
123     predicatesUnSubscribe.And()->In(AppUriPermissionColumn::PERMISSION_TYPE, permissionTypes);
124     vector<string> columns = { AppUriPermissionColumn::ID };
125     auto resultSet = rdbStore->Query(predicatesUnSubscribe, columns);
126     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_ERR, "Can not query URIPERMISSION");
127 
128     int32_t count = 0;
129     auto ret = resultSet->GetRowCount(count);
130     CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, E_ERR, "GetRowCount failed ret:%{public}d", ret);
131     return count;
132 }
133 
CountHideSensitive(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)134 static int32_t CountHideSensitive(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
135 {
136     NativeRdb::AbsRdbPredicates predicatesUnSubscribe(AppUriSensitiveColumn::APP_URI_SENSITIVE_TABLE);
137     vector<string> columns = { AppUriPermissionColumn::ID };
138     auto resultSet = rdbStore->Query(predicatesUnSubscribe, columns);
139     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_ERR, "Can not query URIPERMISSION");
140 
141     int32_t count = 0;
142     auto ret = resultSet->GetRowCount(count);
143     CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, E_ERR, "GetRowCount failed ret:%{public}d", ret);
144     return count;
145 }
146 
TryUnSubscribeAppState(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)147 static void TryUnSubscribeAppState(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
148 {
149     int32_t countPermission = CountTemporaryPermission(rdbStore);
150     int32_t countSensitive = CountHideSensitive(rdbStore);
151     bool cond = (countPermission < 0 || countSensitive < 0);
152     CHECK_AND_PRINT_LOG(!cond, "TryUnSubscribeAppState System exception");
153 
154     if (countPermission == 0 && countSensitive == 0) {
155         MedialibraryAppStateObserverManager::GetInstance().UnSubscribeAppState();
156         MEDIA_INFO_LOG("No temporary permission record remains ,UnSubscribeAppState");
157     }
158 }
159 
DeleteTemporaryPermission(const std::shared_ptr<MediaLibraryRdbStore> rdbStore,const uint32_t tokenId)160 static int32_t DeleteTemporaryPermission(const std::shared_ptr<MediaLibraryRdbStore> rdbStore, const uint32_t tokenId)
161 {
162     NativeRdb::AbsRdbPredicates predicates(AppUriPermissionColumn::APP_URI_PERMISSION_TABLE);
163     predicates.EqualTo(AppUriPermissionColumn::TARGET_TOKENID, static_cast<int64_t>(tokenId));
164     vector<string> permissionTypes;
165     permissionTypes.emplace_back(to_string(
166         static_cast<int32_t>(PhotoPermissionType::TEMPORARY_READ_IMAGEVIDEO)));
167     permissionTypes.emplace_back(to_string(
168         static_cast<int32_t>(PhotoPermissionType::TEMPORARY_WRITE_IMAGEVIDEO)));
169     permissionTypes.emplace_back(to_string(
170         static_cast<int32_t>(PhotoPermissionType::TEMPORARY_READWRITE_IMAGEVIDEO)));
171     predicates.And()->In(AppUriPermissionColumn::PERMISSION_TYPE, permissionTypes);
172     int32_t deletedRows = -1;
173 
174     auto ret = rdbStore->Delete(deletedRows, predicates);
175     bool cond = (ret != NativeRdb::E_OK || deletedRows < 0);
176     CHECK_AND_PRINT_LOG(!cond, "Story Delete db failed, errCode = %{public}d", ret);
177     MEDIA_INFO_LOG("Uripermission Delete retVal: %{public}d, deletedRows: %{public}d", ret, deletedRows);
178 
179     return deletedRows;
180 }
181 
DeleteHideSensitive(const std::shared_ptr<MediaLibraryRdbStore> rdbStore,const uint32_t tokenId)182 static int32_t DeleteHideSensitive(const std::shared_ptr<MediaLibraryRdbStore> rdbStore, const uint32_t tokenId)
183 {
184     NativeRdb::AbsRdbPredicates predicates(AppUriSensitiveColumn::APP_URI_SENSITIVE_TABLE);
185     predicates.EqualTo(AppUriPermissionColumn::TARGET_TOKENID, static_cast<int64_t>(tokenId));
186     int32_t deletedRows = -1;
187     auto ret = rdbStore->Delete(deletedRows, predicates);
188     bool cond = (ret != NativeRdb::E_OK || deletedRows < 0);
189     CHECK_AND_PRINT_LOG(!cond, "Story Delete db failed, errCode = %{public}d", ret);
190     MEDIA_INFO_LOG("Uripermission Delete retVal: %{public}d, deletedRows: %{public}d", ret, deletedRows);
191 
192     return deletedRows;
193 }
194 
WaitAndRevoke(int64_t tokenId)195 void MedialibraryAppStateObserver::WaitAndRevoke(int64_t tokenId)
196 {
197     MedialibraryAppStateObserverManager::GetInstance().AddTokenId(tokenId, true);
198     std::this_thread::sleep_for(chrono::milliseconds(WAITFOR_REVOKE));
199     if (!MedialibraryAppStateObserverManager::GetInstance().NeedRevoke(tokenId)) {
200         MEDIA_INFO_LOG("MedialibraryAppStateObserver stop revoke tokenId:%{public}ld", static_cast<long>(tokenId));
201         return;
202     }
203     MEDIA_INFO_LOG("MedialibraryAppStateObserver OnAppStopped, tokenId:%{public}ld", static_cast<long>(tokenId));
204     auto rdbStore = MediaLibraryDataManager::GetInstance()->rdbStore_;
205     CHECK_AND_RETURN_LOG(rdbStore != nullptr, "Uripermission Delete failed, rdbStore is null.");
206 
207     int32_t deletedRowsPermission = DeleteTemporaryPermission(rdbStore, tokenId);
208     int32_t deletedRowsSensitive = DeleteHideSensitive(rdbStore, tokenId);
209     MedialibraryAppStateObserverManager::GetInstance().RemoveTokenId(tokenId);
210     TryUnSubscribeAppState(rdbStore);
211 }
212 
OnAppStopped(const AppStateData & appStateData)213 void MedialibraryAppStateObserver::OnAppStopped(const AppStateData &appStateData)
214 {
215     auto tokenId = appStateData.accessTokenId;
216     if (!MedialibraryAppStateObserverManager::GetInstance().IsContainTokenId(tokenId)) {
217         return;
218     }
219     MEDIA_INFO_LOG("MedialibraryAppStateObserver TokenId: %{public}ld OnAppStopped, revoke permission",
220         static_cast<long>(tokenId));
221     std::thread revokeThread([this, tokenId]() { this->WaitAndRevoke(tokenId); });
222     revokeThread.detach();
223 }
224 
OnAppStarted(const AppStateData & appStateData)225 void MedialibraryAppStateObserver::OnAppStarted(const AppStateData &appStateData)
226 {
227     auto tokenId = appStateData.accessTokenId;
228     if (MedialibraryAppStateObserverManager::GetInstance().IsContainTokenId(tokenId)) {
229         MEDIA_INFO_LOG("MedialibraryAppStateObserver OnAppStarted tokenId: %{public}ld reStart, cancel revoke",
230             static_cast<long>(tokenId));
231         MedialibraryAppStateObserverManager::GetInstance().AddTokenId(tokenId, false);
232     }
233 }
234 }  // namespace Media
235 }  // namespace OHOS
236